Obtendo o valor da exceção em Python

239

Se eu tiver esse código:

try:
    some_method()
except Exception, e:

Como posso obter esse valor de exceção (representação de cadeia, quero dizer)?

Frias
fonte

Respostas:

323

usar str

try:
    some_method()
except Exception as e:
    s = str(e)

Além disso, a maioria das classes de exceção terá um argsatributo. Muitas vezes, args[0]será uma mensagem de erro.

Deve-se observar que o uso de apenas strretornará uma string vazia se não houver mensagem de erro, enquanto o uso de reprpyfunc recomenda, pelo menos, exibirá a classe da exceção. Minha opinião é que, se você está imprimindo, é para um usuário final que não se importa com a classe e quer apenas uma mensagem de erro.

Realmente depende da classe de exceção com a qual você está lidando e como ela é instanciada. Você tinha algo em particular em mente?

aaronasterling
fonte
Estou imprimindo isso para fazer um relatório, o str (e) está bem, eu acho. Muito obrigado
Frias
8
Eu preferiria usar e.messageporque args[0]pode não ser realmente uma mensagem.
cedbeu
3
repr (e) também é útil se você deseja obter a exceção completa (por exemplo, NameError ("nome global 'variável' não está definida",)), em vez de "nome global 'variável' não está definida"
Ben Morris
49
esta resposta é perigoso, uma vez que irá falhar por exceções unicode como este: raise Exception(u'jörn'). A falha é especialmente ruim, porque você nunca verá a exceção real, mas apenas a UnicodeDecodeError. Se você não conhece a codificação da exceção (e na maioria das vezes não conhece), deve trabalhar repr(e)ou, se realmente precisar, usar outro bloco try-except em seu tratamento de exceções, que captura UnicodeDecodeErrors e volta para repr(e).
Jörn Hees
11
Concorde com @ JörnHees. Não consigo contar o número de vezes que str(ou mesmo unicodeou .format) causou erros devido ao manuseio Unicode. Se você não tiver controle completo do conteúdo da mensagem de erro, use SEMPRE reprpara evitar erros Unicode inesperados.
Kenny Trytek
185

Use repr () e A diferença entre usar repr e str

Usando repr:

>>> try:
...     print(x)
... except Exception as e:
...     print(repr(e))
... 
NameError("name 'x' is not defined")

Usando str:

>>> try:
...     print(x)
... except Exception as e:
...     print(str(e))
... 
name 'x' is not defined
pyfunc
fonte
2
ah, repré graças úteis, parece que qualquer outra coisa unicode, str, codificando, ... pode gerar uma exceção dependendo da entrada. Não é bem útil quando se tenta manter a exceção para olhar, mas repr é exception-safeque parece
dashesy
2
Isso é muito melhor do que qualquer str()solução semelhante, porque na verdade inclui o tipo de exceção. Com str()cheguei 'status'enquanto repr()cheguei KeyError('status')e fiquei tipo "aaaaah, agora entendo o erro".
Jlh
27

Mesmo sabendo que essa é uma pergunta antiga, gostaria de sugerir o uso do tracebackmódulo para lidar com a saída das exceções.

Use traceback.print_exc()para imprimir a exceção atual para o erro padrão, assim como seria impressa se permanecesse não capturada ou traceback.format_exc()para obter a mesma saída que uma string. Você pode passar vários argumentos para qualquer uma dessas funções se desejar limitar a saída ou redirecionar a impressão para um objeto semelhante a um arquivo.

Blckknght
fonte
23

Outra maneira ainda não foi dada:

try:
    1/0
except Exception, e:
    print e.message

Resultado:

integer division or modulo by zero

args[0] pode realmente não ser uma mensagem.

str(e)pode retornar a string com aspas circundantes e, possivelmente, com o uunicode inicial:

'integer division or modulo by zero'

repr(e) fornece a representação completa da exceção, que provavelmente não é o que você deseja:

"ZeroDivisionError('integer division or modulo by zero',)"

editar

Foi mal !!! Parece que BaseException.message foi preterido de2.6 , finalmente, parece definitivamente que ainda não existe uma maneira padronizada de exibir mensagens de exceção. Então, acho que o melhor é lidar com e.argse str(e)dependendo de suas necessidades (e possivelmente e.messagese a biblioteca que você está usando depende desse mecanismo).

Por exemplo, com pygraphviz, e.messageé a única maneira de exibir corretamente a exceção, usando str(e)envolverá a mensagem u''.

Mas com MySQLdb, a maneira correta de recuperar a mensagem é e.args[1]: e.messageestá vazia e str(e)será exibida'(ERR_CODE, "ERR_MSG")'

cedbeu
fonte
0

Para python2, é melhor usar e.messagepara obter a mensagem de exceção, isso evitará possível UnicodeDecodeError. Mas yes e.messageestará vazio para alguns tipos de exceções OSError, como , nesse caso, podemos adicionar um exc_info=Trueà nossa função de log para não perder o erro.
Para python3, acho seguro usá-lo str(e).

apporc
fonte
0

Se você não souber o tipo / origem do erro, tente:

import sys
try:
    doSomethingWrongHere()
except:
    print('Error: {}'.format(sys.exc_info()[0]))

Mas esteja ciente, você receberá o aviso pep8:

[W] PEP 8 (E722): do not use bare except
Kostanos
fonte
0

Para inspecionar a mensagem de erro e fazer algo com ela (com Python 3) ...

try:
    some_method()
except Exception as e:
    if {value} in e.args:
        {do something}
DanGoodrick
fonte