O Python 3 possui a cláusula raise
...from
para encadear exceções. A resposta de Glenn é ótima para o Python 2.7, mas ele usa apenas o rastreio da exceção original e joga fora a mensagem de erro e outros detalhes. Aqui estão alguns exemplos no Python 2.7 que adicionam informações de contexto do escopo atual à mensagem de erro da exceção original, mas mantêm outros detalhes intactos.
Tipo de exceção conhecido
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
Esse tipo de raise
instrução usa o tipo de exceção como a primeira expressão, os argumentos do construtor da classe de exceção em uma tupla como a segunda expressão e o retorno como a terceira expressão. Se você estiver executando antes do Python 2.2, consulte os avisos em sys.exc_info()
.
Qualquer tipo de exceção
Aqui está outro exemplo de propósito mais geral, se você não souber que tipo de exceção seu código pode ter que capturar. A desvantagem é que ele perde o tipo de exceção e apenas gera um RuntimeError. Você precisa importar o traceback
módulo.
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
Modifique a mensagem
Aqui está outra opção se o tipo de exceção permitir que você adicione contexto a ele. Você pode modificar a mensagem da exceção e, em seguida, aumentá-la.
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
Isso gera o seguinte rastreamento de pilha:
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']
Você pode ver que ele mostra a linha onde check_output()
foi chamada, mas a mensagem de exceção agora inclui a linha de comando.