Eu quero conseguir algo assim:
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')
Mas o que eu recebo é:
Traceback..
IOError('Stuff')
Alguma pista de como conseguir isso? Como fazer isso em Python 2 e 3?
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).Respostas:
Eu faria assim, para alterar seu tipo
foo()
não exigirá também a alteraçãobar()
.Atualização 1
Aqui está uma pequena modificação que preserva o retorno original:
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 emBaseException
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çãobar()
. Observe também que haverá a linha:nas mensagens de retorno exibidas.
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.fonte
__str__
, você poderá obter resultados indesejáveis. Observe também que o segundo argumento é passado para o construtor fornecido pelo primeiro argumento, o que gera uma certa disparatetype(e)(type(e)(e.message)
. Em terceiro lugar, o e.message é preterido em favor do e.args [0].Caso você tenha vindo aqui procurando uma solução para o Python 3, o manual diz:
Exemplo:
Que fica assim no final:
Transformar uma
TypeError
mensagem totalmente indefinida em uma boa mensagem com dicas para uma solução sem estragar a Exceção original.fonte
e.args
, mas é uma tupla, portanto não pode ser alterada. Então, primeiro copieargs
para uma lista, modifique-a e copie-a novamente como uma tupla:args = list(e.args)
args[0] = 'bar'
e.args = tuple(args)
Supondo que você não queira ou não possa modificar foo (), faça o seguinte:
Esta é realmente a única solução aqui que resolve o problema no Python 3 sem uma mensagem feia e confusa de "Durante o tratamento da exceção acima, ocorreu outra exceção".
Caso a linha de re-raise deva ser adicionada ao rastreamento da pilha, escrever em
raise e
vez deraise
fará o truque.fonte
e.args = ('mynewstr' + e.args[0],) + e.args[1:]
Eu não gosto de todas as respostas dadas até agora. Eles ainda são muito detalhados. Na saída de código e mensagem.
Tudo o que eu quero é o stacktrace apontando para a exceção de origem, sem nenhuma exceção, portanto, sem criação de novas exceções, apenas re-aumentando o original com todas as informações relevantes. estados quadro da pilha, que levaram até lá.
Steve Howard deu uma boa resposta que eu quero estender, não, reduzir ... apenas para python 3.
A única novidade é o parâmetro de expansão / descompactação que o torna pequeno e fácil o suficiente para eu usar.
Tente:
Isso lhe dará:
Uma impressão bonita e simples pode ser algo como
fonte
Uma abordagem prática que usei é usar o atributo de classe como armazenamento para obter detalhes, pois o atributo de classe pode ser acessado no objeto de classe e na instância de classe:
Então no seu código:
E ao detectar um erro:
fonte
Diferentemente das respostas anteriores, isso funciona com exceções muito ruins
__str__
. No entanto, ele modifica o tipo, a fim de considerar fatores inúteis__str__
implementações .Ainda gostaria de encontrar uma melhoria adicional que não modifique o tipo.
O retorno original e o tipo (nome) são preservados.
fonte
Fornecerei um trecho de código que uso com frequência sempre que quiser adicionar informações extras a uma exceção. Eu trabalho tanto em Python 2.7 e 3.6.
O código acima resulta na seguinte saída:
Sei que isso se desvia um pouco do exemplo fornecido na pergunta, mas, no entanto, espero que alguém ache útil.
fonte
Você pode definir sua própria exceção que herda de outra e criar seu próprio construtor para definir valor.
Por exemplo:
fonte
message
exceção original (mas poderia ser corrigido, eu acho).Talvez
fonte