У Python 3 є пункт raise...from для ланцюжкових винятків. Відповідь Глена чудово підходить для Python 2.7, але він використовує лише оригінальний відстеження виключення та викидає повідомлення про помилку та інші деталі. Ось декілька прикладів у Python 2.7, які додають інформацію про контекст із поточного діапазону у вихідне повідомлення про помилку виключення, але зберігають інші деталі недоторканими.
Відомий тип винятку
try:
sock_common = xmlrpclib.ServerProxy(rpc_url+'/common')
self.user_id = sock_common.login(self.dbname, username, self.pwd)
except IOError:
_, ex, traceback = sys.exc_info()
message = "Connecting to '%s': %s." % (config['connection'],
ex.strerror)
raise IOError, (ex.errno, message), traceback
Цей аромат raiseвисловлення приймає тип винятку як перший вираз, конструктор класу винятків аргументує кортеж як другий вираз, а зворотний зворот - як третій вираз. Якщо ви працюєте раніше, ніж Python 2.2, дивіться попередження на sys.exc_info().
Будь-який тип винятку
Ось ще один приклад, який має більш загальне призначення, якщо ви не знаєте, які винятки можуть уловлювати ваш код. Мінусом є те, що він втрачає тип винятку і просто підвищує RuntimeError. Вам потрібно імпортувати tracebackмодуль.
except Exception:
extype, ex, tb = sys.exc_info()
formatted = traceback.format_exception_only(extype, ex)[-1]
message = "Importing row %d, %s" % (rownum, formatted)
raise RuntimeError, message, tb
Змініть Повідомлення
Ось ще один варіант, якщо тип виключення дозволить вам додати до нього контекст. Ви можете змінити повідомлення про виключення, а потім повторно змінити його.
import subprocess
try:
final_args = ['lsx', '/home']
s = subprocess.check_output(final_args)
except OSError as ex:
ex.strerror += ' for command {}'.format(final_args)
raise
Це генерує такий слід стека:
Traceback (most recent call last):
File "/mnt/data/don/workspace/scratch/scratch.py", line 5, in <module>
s = subprocess.check_output(final_args)
File "/usr/lib/python2.7/subprocess.py", line 566, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory for command ['lsx', '/home']
Ви можете бачити, що він показує рядок, куди check_output()дзвонили, але повідомлення про виключення тепер включає командний рядок.