我想达到这样的效果:
def foo():
try:
raise IOError('Stuff ')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
e.message = e.message + 'happens at %s' % arg1
raise
bar('arg1')
Traceback...
IOError('Stuff Happens at arg1')
但我得到的是:
Traceback..
IOError('Stuff')
关于如何实现这一点,有什么线索吗?如何在Python 2和3中都做到这一点?
如果你来这里寻找Python 3的解决方案,手册上说:
当引发一个新的异常时(而不是使用一个简单的raise来重新引发当前正在处理的异常),隐式异常上下文可以通过使用from和raise来补充显式原因:
raise new_exc from original_exc
例子:
try:
return [permission() for permission in self.permission_classes]
except TypeError as e:
raise TypeError("Make sure your view's 'permission_classes' are iterable. "
"If you use '()' to generate a set with a single element "
"make sure that there is a comma behind the one (element,).") from e
最后是这样的:
2017-09-06 16:50:14,797 [ERROR] django.request: Internal Server Error: /v1/sendEmail/
Traceback (most recent call last):
File "venv/lib/python3.4/site-packages/rest_framework/views.py", line 275, in get_permissions
return [permission() for permission in self.permission_classes]
TypeError: 'type' object is not iterable
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
# Traceback removed...
TypeError: Make sure your view's Permission_classes are iterable. If
you use parens () to generate a set with a single element make
sure that there is a (comma,) behind the one element.
将一个完全无描述的TypeError转换为一个带有解决方案提示的漂亮消息,而不会搞乱原始异常。
我使用的一个方便的方法是使用类属性作为详细信息的存储,因为类属性可以从类对象和类实例中访问:
class CustomError(Exception):
def __init__(self, details: Dict):
self.details = details
然后在代码中:
raise CustomError({'data': 5})
当捕获错误时:
except CustomError as e:
# Do whatever you want with the exception instance
print(e.details)
与之前的答案不同,这适用于非常糟糕的__str__异常。
但是,它确实修改了类型,以便剔除无用的__str__实现。
我仍然希望找到一个不修改类型的额外改进。
from contextlib import contextmanager
@contextmanager
def helpful_info():
try:
yield
except Exception as e:
class CloneException(Exception): pass
CloneException.__name__ = type(e).__name__
CloneException.__module___ = type(e).__module__
helpful_message = '%s\n\nhelpful info!' % e
import sys
raise CloneException, helpful_message, sys.exc_traceback
class BadException(Exception):
def __str__(self):
return 'wat.'
with helpful_info():
raise BadException('fooooo')
原始的回溯和类型(名称)被保留。
Traceback (most recent call last):
File "re_raise.py", line 20, in <module>
raise BadException('fooooo')
File "/usr/lib64/python2.6/contextlib.py", line 34, in __exit__
self.gen.throw(type, value, traceback)
File "re_raise.py", line 5, in helpful_info
yield
File "re_raise.py", line 20, in <module>
raise BadException('fooooo')
__main__.BadException: wat.
helpful info!