Eu faria assim, para alterar seu tipo foo()
não exigirá também a alteração bar()
.
def foo():
try:
raise IOError('Stuff')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
raise type(e)(e.message + ' happens at %s' % arg1)
bar('arg1')
Traceback (most recent call last):
File "test.py", line 13, in <module>
bar('arg1')
File "test.py", line 11, in bar
raise type(e)(e.message + ' happens at %s' % arg1)
IOError: Stuff happens at arg1
Atualização 1
Aqui está uma pequena modificação que preserva o retorno original:
...
def bar(arg1):
try:
foo()
except Exception as e:
import sys
raise type(e), type(e)(e.message +
' happens at %s' % arg1), sys.exc_info()[2]
bar('arg1')
Traceback (most recent call last):
File "test.py", line 16, in <module>
bar('arg1')
File "test.py", line 11, in bar
foo()
File "test.py", line 5, in foo
raise IOError('Stuff')
IOError: Stuff happens at arg1
Atualização 2
Para Python 3.x, o código na minha primeira atualização é sintaticamente incorreto mais a idéia de ter um message
atributo em BaseException
foi recolhido em uma mudança de PEP 352 em 2012-05-16 (minha primeira atualização foi publicada em 2012-03-12) . Portanto, atualmente, no Python 3.5.2 de qualquer maneira, você precisaria fazer algo nesse sentido para preservar o retorno e não codificar o tipo de exceção na função bar()
. Observe também que haverá a linha:
During handling of the above exception, another exception occurred:
nas mensagens de retorno exibidas.
# for Python 3.x
...
def bar(arg1):
try:
foo()
except Exception as e:
import sys
raise type(e)(str(e) +
' happens at %s' % arg1).with_traceback(sys.exc_info()[2])
bar('arg1')
Atualização 3
Um comentarista perguntou se havia uma maneira de funcionar no Python 2 e 3. Embora a resposta possa parecer "Não" devido às diferenças de sintaxe, há é uma maneira de contornar isso usando uma função auxiliar como reraise()
nasix
add- no módulo. Portanto, se você preferir não usar a biblioteca por algum motivo, a seguir está uma versão autônoma simplificada.
Observe também que, como a exceção é gerada novamente dentro da reraise()
função, ela aparecerá em qualquer retorno de retorno gerado, mas o resultado final é o que você deseja.
import sys
if sys.version_info.major < 3: # Python 2?
# Using exec avoids a SyntaxError in Python 3.
exec("""def reraise(exc_type, exc_value, exc_traceback=None):
raise exc_type, exc_value, exc_traceback""")
else:
def reraise(exc_type, exc_value, exc_traceback=None):
if exc_value is None:
exc_value = exc_type()
if exc_value.__traceback__ is not exc_traceback:
raise exc_value.with_traceback(exc_traceback)
raise exc_value
def foo():
try:
raise IOError('Stuff')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
reraise(type(e), type(e)(str(e) +
' happens at %s' % arg1), sys.exc_info()[2])
bar('arg1')
message
atributo Exception , encontrei essa pergunta de SO, BaseException.message descontinuado no Python 2.6 , que parece indicar que seu uso agora é desencorajado (e por que não está nos documentos).