python 引发错误而不追溯

oyjwcjzk  于 2022-12-21  发布在  Python
关注(0)|答案(5)|浏览(163)

我想使用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 Package 器,我不希望用户看到回溯,而是看到API响应代码和错误消息。
有办法吗?

brvekthn

brvekthn1#

我遇到过一个类似的问题,父类使用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...
envsm3lx

envsm3lx2#

问题不在于引发什么,而在于当你的程序以异常终止时,python解释器做了什么(它只是打印堆栈跟踪)。如果你想避免它,你应该做的是在你想“隐藏”堆栈跟踪的所有东西周围放置try except块,比如:

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

另一种方法是修改exeption处理程序sys.excepthook(type, value, traceback),以执行您自己的逻辑,例如

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

import sys
sys.excepthook = my_exchandler

你甚至可以对异常type进行条件处理,然后执行特定的逻辑,如果它是你的异常类型,否则就退回到原来的异常类型。

rkkpypqq

rkkpypqq3#

修改日期:Alec answer

@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:通过@DrJohnASevenson评论改进代码

6tdlim6h

6tdlim6h4#

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

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

假的error_response()函数可以做任何事情,比如返回一个空响应或一个错误消息。你仍然应该使用正确的HTTP状态代码。在这个示例中,你应该返回一个404。
你应该优雅地处理异常,但是你不应该对客户端完全隐藏错误。在NoSuchElementError异常的情况下,听起来像是应该通知客户端(错误可能是在他们那端)。

cnwbcb6i

cnwbcb6i5#

可以创建一个接受两个值的类;键入并编写自定义异常消息的代码。然后,您可以在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

相关问题