Tengo una función llamada por el programa principal:
try:
someFunction()
except:
print "exception happened!"
pero en medio de la ejecución de la función genera una excepción, por lo que salta a la except
parte.
¿Cómo puedo ver exactamente qué sucedió en el someFunction()
que causó la excepción?
except:
(sin bareraise
), excepto tal vez una vez por programa, y preferiblemente no entonces.except
cláusulas, no necesitará verificar el tipo de excepción, eso es lo que generalmente se hace para actuar de acuerdo con un tipo de excepción específico.except
bloque, la excepción está disponible a través de lasys.exc_info()
función: esta función devuelve una tupla de tres valores que proporcionan información sobre la excepción que se está manejando actualmente.Respuestas:
Todas las otras respuestas señalan que no debe atrapar excepciones genéricas, pero nadie parece querer decirle por qué, lo cual es esencial para comprender cuándo puede romper la "regla". Aquí hay una explicación. Básicamente, es para que no te escondas:
Entonces, siempre que tenga cuidado de no hacer ninguna de esas cosas, está bien detectar la excepción genérica. Por ejemplo, podría proporcionar información sobre la excepción al usuario de otra manera, como:
Entonces, ¿cómo atrapar la excepción genérica? Hay varias formas Si solo desea el objeto de excepción, hágalo así:
¡ Asegúrese
message
de llamar la atención del usuario de una manera difícil de perder! Imprimirlo, como se muestra arriba, puede no ser suficiente si el mensaje está enterrado en muchos otros mensajes. No captar la atención de los usuarios equivale a tragarse todas las excepciones, y si hay una impresión que debería haber salido después de leer las respuestas en esta página, es que esto no es algo bueno . Al finalizar el bloque except con unaraise
declaración se solucionará el problema volviendo a plantear de forma transparente la excepción que se detectó.La diferencia entre lo anterior y el uso
except:
sin ningún argumento es doble:except:
no te da el objeto de excepción para inspeccionarSystemExit
,KeyboardInterrupt
yGeneratorExit
no están atrapados por el código anterior, que generalmente es lo que quieres. Ver la jerarquía de excepciones .Si también desea el mismo stacktrace que obtiene si no captura la excepción, puede obtenerlo así (aún dentro de la cláusula except):
Si usa el
logging
módulo, puede imprimir la excepción en el registro (junto con un mensaje) como este:Si desea profundizar y examinar la pila, ver variables, etc., use la
post_mortem
función delpdb
módulo dentro del bloque except:He encontrado que este último método es invaluable al buscar errores.
fuente
Obtenga el nombre de la clase a la que pertenece el objeto de excepción:
y el uso de la función print_exc () también imprimirá el seguimiento de la pila, que es información esencial para cualquier mensaje de error.
Me gusta esto:
Obtendrá una salida como esta:
Y después de la impresión y el análisis, el código puede decidir no manejar excepciones y simplemente ejecutar
raise
:Salida:
Y el intérprete imprime la excepción:
Después de que la
raise
excepción original continúa propagándose más arriba en la pila de llamadas. ( Tenga cuidado con las posibles dificultades ) Si genera una nueva excepción, conlleva un nuevo seguimiento de pila (más corto).Salida:
Observe cómo el rastreo no incluye la
calculate()
función de la línea,9
que es el origen de la excepción originale
.fuente
traceback.format_exc()
asíe.__class__.__name__
¿Es esto lo mismo quetype(e).__name__
, como sugiere la respuesta anterior?Por lo general, no debe detectar todas las posibles excepciones,
try: ... except
ya que esto es demasiado amplio. Simplemente atrape los que se espera que sucedan por cualquier razón. Si realmente debe hacerlo, por ejemplo, si desea obtener más información sobre algún problema durante la depuración, debe hacerlofuente
try: ... except Exception:
muchas cosas, por ejemplo, el uso de bibliotecas dependientes de la red, o una masajista de datos que puede enviarle cosas extrañas. Naturalmente, también tengo un registro adecuado. Esto es crucial para permitir que el programa continúe operando en caso de un solo error en los datos de entrada.smtplib
?A menos que
somefunction
sea una función heredada codificada muy mal, no debería necesitar lo que está pidiendo.Use múltiples
except
cláusulas para manejar de diferentes maneras diferentes excepciones:El punto principal es que no debe atrapar una excepción genérica, sino solo las que necesita. Estoy seguro de que no desea ocultar errores o errores inesperados.
fuente
La mayoría de las respuestas apuntan a la
except (…) as (…):
sintaxis (con razón), pero al mismo tiempo nadie quiere hablar de un elefante en la habitación, donde el elefante está ensys.exc_info()
funcionamiento. De la documentación del módulo sys (énfasis mío):Creo que
sys.exc_info()
podría tratarse como la respuesta más directa a la pregunta original de ¿Cómo sé qué tipo de excepción ocurrió?fuente
except
. Solo por completo,exctype, value = sys.exc_info()[:2]
le indicaremos el tipo de excepción que luego se puede utilizar en elexcept
.try: someFunction () excepto Exception, exc:
fuente
exc.__class__.__name__
ya se había sugerido en la respuesta de Alex - stackoverflow.com/a/9824060/95735Estas respuestas están bien para la depuración, pero para probar mediante programación la excepción,
isinstance(e, SomeException)
puede ser útil, ya que también prueba las subclasesSomeException
, para que pueda crear una funcionalidad que se aplique a las jerarquías de excepciones.fuente
Así es como estoy manejando mis excepciones. La idea es intentar resolver el problema si eso es fácil, y luego agregar una solución más deseable si es posible. No resuelva el problema en el código que genera la excepción, o ese código pierde el rastro del algoritmo original, que debe escribirse en el punto. Sin embargo, pase los datos necesarios para resolver el problema y devuelva un lambda en caso de que no pueda resolver el problema fuera del código que lo genera.
Por ahora, dado que no quiero pensar tangencialmente para el propósito de mi aplicación, no he agregado ninguna solución complicada. Pero en el futuro, cuando sepa más sobre las posibles soluciones (dado que la aplicación está diseñada más), podría agregar un diccionario de soluciones indexadas por
during
.En el ejemplo que se muestra, una solución podría ser buscar datos de aplicaciones almacenados en otro lugar, por ejemplo, si el archivo 'app.p' se eliminó por error.
Por ahora, dado que escribir el controlador de excepciones no es una idea inteligente (todavía no conocemos las mejores formas de resolverlo, porque el diseño de la aplicación evolucionará), simplemente devolvemos la solución fácil que es actuar como si estuviéramos corriendo la aplicación por primera vez (en este caso).
fuente
Para agregar a la respuesta de Lauritz, creé un decorador / contenedor para el manejo de excepciones y el contenedor registra qué tipo de excepción ocurrió.
Esto se puede invocar en un método de clase o una función independiente con el decorador:
@general_function_handler
Consulte mi blog para ver el ejemplo completo: http://ryaneirwin.wordpress.com/2014/05/31/python-decorators-and-exception-handling/
fuente
Puede comenzar como Lauritz recomienda, con:
y luego solo para que me
print ex
guste:fuente
La excepción real se puede capturar de la siguiente manera:
Puede obtener más información sobre las excepciones en The Python Tutorial .
fuente
Su pregunta es: "¿Cómo puedo ver exactamente qué sucedió en someFunction () que causó la excepción?"
Me parece que no está preguntando cómo manejar excepciones imprevistas en el código de producción (como se suponía en muchas respuestas), sino cómo averiguar qué está causando una excepción particular durante el desarrollo.
La forma más fácil es utilizar un depurador que pueda detenerse donde se produce la excepción no detectada, preferiblemente sin salir, para que pueda inspeccionar las variables. Por ejemplo, PyDev en el IDE de código abierto de Eclipse puede hacer eso. Para habilitar eso en Eclipse, abra la perspectiva Depuración, seleccione
Manage Python Exception Breakpoints
en elRun
menú y verifiqueSuspend on uncaught exceptions
.fuente
Simplemente abstenerse de atrapar la excepción y el rastreo que Python imprime le dirá qué excepción ocurrió.
fuente