请参阅以下代码
def ex_string(ex):
return "Error:{} Traceback:{}".format(ex, traceback.format_exc())
def map_values(listing):
...
obj = listing['value']
...
def process_listing(listing):
try:
listing = map_values(listing)
except Exception as ex:
do_some_handling(listing)
print ex_string(ex) # this stack shows actual line inside map_values
raise ex
def start():
for listing in listings:
try:
process_listing(listing)
save_listing(listing)
except Exception as ex:
error = ex_string(ex) #this stack shows map_values function only
log_error(error)
如上所述,当listing
不包含'value'
元素时,我不知道哪一行导致了问题,我从log中知道的所有内容都在map_values
函数内部,如何从首次引发异常的地方获取完整的堆栈跟踪?在这种情况下obj = listing['value']
在raise
子句中使用没有参数的except
来重新处理您使用其原始回溯处理的异常:
def process_listing(listing):
try:
listing = map_values(listing)
except Exception as ex:
do_some_handling(listing)
print ex_string(ex)
raise # no ex
没有参数的raise
意味着您希望将正在处理的异常视为未处理,因此它将继续使用相同的回溯进行传播。
在这里使用带有一个参数的raise
意味着你发出异常处理程序遇到错误的信号,因此Python构造了一个指向异常处理程序中的raise
的新堆栈跟踪。
请注意,带有参数的raise
在Python 3上表现不同,其中异常记录其关联的回溯。在Python 3上,raise
和raise ex
都将保留原始的追溯,但raise ex
将为raise ex
线的追溯添加额外的记录。
此外,Python使用一个奇怪的回溯构造系统,其中异常在最初引发时没有堆栈跟踪,并且每次它通过堆栈帧冒泡时,会向堆栈跟踪添加一个额外的帧记录。 (对于带有1或2个参数的raise
,也添加了一条记录,但不是0或3,因此前一段中的差异。)由于此回溯构造系统,回溯将不包含有关异常框架的任何信息传播到,并且异常的异常处理模式可能导致回溯看起来像在初始raise
点处堆栈的样子。