我想使用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响应代码和错误消息。
有办法吗?
答案 0 :(得分:3)
问题不在于提升任何东西,而在于python解释器的作用,当程序以异常终止时(它只是打印堆栈跟踪)。如果你想避免它,你应该做的是将try除了阻止你想要“隐藏”堆栈跟踪的所有内容,例如:
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
并且如果它是你的异常类型则执行特定的逻辑,否则 - 退回原始异常。
答案 1 :(得分:3)
修改后的@Alec answer:
end reconfigure
用法:
@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
如果只需要隐藏回溯而不修改异常消息,请使用此选项。在Python 3.8上进行了测试
UPD:通过@DrJohnAStevenson评论改进的代码
答案 2 :(得分:1)
捕获异常,记录并返回指示消费者出现问题的内容(当查询失败时发回200可能会导致客户端出现问题)。
try:
return do_something()
except NoSuchElementError as e:
logger.error(e)
return error_response()
假error_response()
函数可以执行任何操作,返回空响应或错误消息。您仍应使用正确的HTTP状态代码。听起来你应该在这个例子中返回404。
您应该优雅地处理异常,但不应该完全隐藏客户端的错误。如果您的NoSuchElementError
异常,则听起来应该通知客户端(错误可能在他们的结尾)。
答案 3 :(得分:1)
我遇到了类似的问题,其中父类使用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...