在没有回溯的情况下引发错误

问题描述 投票:0回答:5

我想使用

raise
而不在屏幕上打印回溯。我知道如何使用
try ..catch
做到这一点,但没有找到使用
raise
的方法。

这是一个例子:

def my_function(self):
    resp = self.resp
    if resp.status_code == 404:
        raise NoSuchElementError('GET'+self.url+'{}'.format(resp.status_code)) 
    elif resp.status_code == 500:
        raise ServerErrorError('GET'+self.url+'{}'.format(resp.status_code))

执行此操作时,如果出现 404,则回溯将打印在屏幕上。

Traceback (most recent call last):
  File "test.py", line 32, in <module>
    print ins.my_function()
  File "api.py", line 820, in my_function
    raise NoSuchElementError('GET ' + self.url + ' {} '.format(resp.status_code)) 

这是一个 API 包装器,我不希望用户看到回溯,而是看到 API 响应代码和错误消息。

有办法做到吗?

python api wrapper
5个回答
5
投票

问题不在于引发任何内容,而在于当程序因异常终止时(它只是打印堆栈跟踪)时 python 解释器所做的事情。如果你想避免它,你应该做的就是在你想要“隐藏”堆栈跟踪的所有内容周围放置 try except 块,例如:

def main():
  try:
    actual_code()
  except Exception as e:
    print(e)

另一种方法是修改异常处理程序,

sys.excepthook(type, value, traceback)
,以执行您自己的逻辑,例如

def my_exchandler(type, value, traceback):
  print(value)

import sys
sys.excepthook = my_exchandler

您甚至可以设置异常条件

type
并执行特定逻辑(如果这是您的异常类型),否则 - 退回到原始异常。


5
投票

我遇到了类似的问题,其中父类使用

raise
上的异常值来传递消息,但我不想转储回溯。 @lejlot 使用
sys.excepthook
提供了一个很好的解决方案,但我需要在更有限的范围内应用它。修改如下:

import sys
from contextlib import contextmanager

@contextmanager
def except_handler(exc_handler):
    "Sets a custom exception handler for the scope of a 'with' block."
    sys.excepthook = exc_handler
    yield
    sys.excepthook = sys.__excepthook__

然后,使用它:

def my_exchandler(type, value, traceback):
    print(': '.join([str(type.__name__), str(value)]))

with except_handler(my_exchandler):
    raise Exception('Exceptional!')

# -> Exception: Exceptional!

这样,如果块中未引发异常,则将为任何后续异常恢复默认异常处理:

with except_handler(my_exchandler):
    pass

raise Exception('Ordinary...')

# -> Traceback (most recent call last):
# ->   File "raise_and_suppress_traceback.py", line 22, in <module>
# ->     raise Exception('Ordinary...')
# -> Exception: Ordinary...

5
投票

修改@Alec答案

from contextlib import contextmanager

@contextmanager
def disable_exception_traceback():
    """
    All traceback information is suppressed and only the exception type and value are printed
    """
    default_value = getattr(sys, "tracebacklimit", 1000)  # `1000` is a Python's default value
    sys.tracebacklimit = 0
    yield
    sys.tracebacklimit = default_value  # revert changes

用途:

with disable_exception_traceback():
    raise AnyYourCustomException()

如果您只需要隐藏回溯而不修改异常消息,请使用此选项。在 Python 3.8 上测试

UPD:代码由 @DrJohnAStevenson 评论改进


0
投票

捕获异常,记录它并向消费者返回一些指示出现问题的信息(当查询失败时发送 200 可能会给您的客户端带来问题)。

try:
     return do_something()
except NoSuchElementError as e:
    logger.error(e)
    return error_response()

假的

error_response()
函数可以执行任何操作,返回空响应或错误消息。您仍然应该使用正确的 HTTP 状态代码。听起来您应该在这种情况下返回 404。

您应该优雅地处理异常,但不应该完全向客户端隐藏错误。在您的

NoSuchElementError
异常的情况下,听起来应该通知客户(错误可能是在他们这边)。


0
投票

您可以创建一个带有两个值的类;自定义异常消息的类型和代码。之后,您可以在 try/ except 语句中传递该类。

class ExceptionHandler(Exception):
    def __init__(self, exceptionType, code):
        self.exceptionType = exceptionType
        self.code = code
        print(f"Error logged: {self.exceptionType}, Code: {self.code}")
        

try:
    raise(ExceptionHandler(exceptionType=KeyboardInterrupt, code=101))
except Exception:
    pass
© www.soinside.com 2019 - 2024. All rights reserved.