Obteniendo el valor de excepción en Python

239

Si tengo ese código:

try:
    some_method()
except Exception, e:

¿Cómo puedo obtener este valor de excepción (quiero decir, representación de cadena)?

Frias
fuente

Respuestas:

323

utilizar str

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

Además, la mayoría de las clases de excepción tendrán un argsatributo. A menudo, args[0]habrá un mensaje de error.

Cabe señalar que solo usando strdevolverá una cadena vacía si no hay un mensaje de error mientras usarepr como lo recomienda pyfunc al menos mostrará la clase de la excepción. Mi opinión es que si lo está imprimiendo, es para un usuario final que no le importa cuál es la clase y solo quiere un mensaje de error.

Realmente depende de la clase de excepción con la que esté lidiando y cómo se instancia. ¿Tenías algo en particular en mente?

aaronasterling
fuente
Estoy imprimiendo esto para hacer un informe, supongo que str (e) está bien. Muchas gracias
Frias
8
Preferiría usarlo e.messageporque args[0]podría no ser realmente un mensaje.
cedbeu
3
repr (e) también es útil si desea obtener la excepción completa (por ejemplo, NameError ("el nombre global 'variable' no está definido",), en lugar de "nombre global 'variable' no está definido"
Ben Morris
49
esta respuesta es peligroso, ya que se producirá un error de excepciones Unicode como este: raise Exception(u'jörn'). El fallo es especialmente malo, porque nunca verá la excepción real sino solo una UnicodeDecodeError. Si no conoce la codificación de la excepción (y la mayoría de las veces no lo sabe), debe trabajar repr(e)o, si realmente lo necesita, usar otro bloque try-except en su manejo de excepciones que detecta UnicodeDecodeErrors y vuelve a repr(e).
Jörn Hees
11
De acuerdo con @ JörnHees. No puedo contar la cantidad de veces que str(o incluso unicodeo .format) ha causado errores debido al manejo de Unicode. Si no tiene el control completo del contenido del mensaje de error, SIEMPRE use reprpara evitar errores inesperados de Unicode.
Kenny Trytek
186

Use repr () y La diferencia entre usar repr y str

Utilizando repr:

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

Utilizando str:

>>> try:
...     print(x)
... except Exception as e:
...     print(str(e))
... 
name 'x' is not defined
pyfunc
fuente
2
ah, repres útil gracias, parece otra cosa unicode, strque codifica, ... pueden provocar una excepción dependiendo de la entrada. No es muy útil cuando se trata de mantener la excepción a la mirada, pero repr es exception-safeque parece
dashesy
2
Esto es mucho mejor que cualquier str()solución similar, porque en realidad incluye el tipo de excepción. Con str()tengo 'status'mientras repr()que tengo KeyError('status')y dije "aaaaah, ahora entiendo el error".
jlh
27

Aunque me doy cuenta de que esta es una vieja pregunta, me gustaría sugerir que use el tracebackmódulo para manejar la salida de las excepciones.

Utilícelo traceback.print_exc()para imprimir la excepción actual al error estándar, tal como se imprimiría si no se detectara, o traceback.format_exc()para obtener el mismo resultado que una cadena. Puede pasar varios argumentos a cualquiera de esas funciones si desea limitar la salida o redirigir la impresión a un objeto similar a un archivo.

Blckknght
fuente
23

Todavía no se ha dado otra forma:

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

Salida:

integer division or modulo by zero

args[0] en realidad podría no ser un mensaje.

str(e)podría devolver la cadena con comillas circundantes y posiblemente con el inicio usi unicode:

'integer division or modulo by zero'

repr(e) da la representación de excepción completa que probablemente no sea lo que quieres:

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

editar

Culpa mía !!! Parece que BaseException.message ha quedado en desuso2.6 , finalmente, definitivamente parece que todavía no hay una forma estandarizada de mostrar mensajes de excepción. Así que supongo que lo mejor es tratar e.argsy str(e)dependiendo de sus necesidades (y posiblementee.message si la biblioteca que está utilizando depende de ese mecanismo).

Por ejemplo, con pygraphviz, e.messagees la única forma de mostrar correctamente la excepción, usando str(e)rodeará el mensaje con u''.

Pero con MySQLdb, la forma correcta de recuperar el mensaje es e.args[1]: e.messageestá vacío y str(e)mostrará'(ERR_CODE, "ERR_MSG")'

cedbeu
fuente
0

Para python2, es mejor usarlo e.messagepara obtener el mensaje de excepción, esto evitará que sea posible UnicodeDecodeError. Pero sí e.messageestará vacío para algún tipo de excepciones como OSError, en cuyo caso podemos agregar un exc_info=Truea nuestra función de registro para no perder el error.
Para python3, creo que es seguro de usar str(e).

apporc
fuente
0

Si no conoce el tipo / origen del error, puede intentar:

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

Pero tenga en cuenta que recibirá una advertencia pep8:

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

Para inspeccionar el mensaje de error y hacer algo con él (con Python 3) ...

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