我想使用
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 解释器所做的事情。如果你想避免它,你应该做的就是在你想要“隐藏”堆栈跟踪的所有内容周围放置 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
并执行特定逻辑(如果这是您的异常类型),否则 - 退回到原始异常。
我遇到了类似的问题,其中父类使用
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...
修改@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 评论改进
捕获异常,记录它并向消费者返回一些指示出现问题的信息(当查询失败时发送 200 可能会给您的客户端带来问题)。
try:
return do_something()
except NoSuchElementError as e:
logger.error(e)
return error_response()
假的
error_response()
函数可以执行任何操作,返回空响应或错误消息。您仍然应该使用正确的 HTTP 状态代码。听起来您应该在这种情况下返回 404。
您应该优雅地处理异常,但不应该完全向客户端隐藏错误。在您的
NoSuchElementError
异常的情况下,听起来应该通知客户(错误可能是在他们这边)。
您可以创建一个带有两个值的类;自定义异常消息的类型和代码。之后,您可以在 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