2010-10-02 41 views
24

Estoy trabajando en una biblioteca de envío de correo, y quiero poder detectar excepciones producidas por los remitentes (SMTP, Google App Engine, etc.) y envolverlas en excepciones fácilmente identificables específicas de mi biblioteca (ConnectionError, MessageSendError, etc.), con la traza original intacta para que pueda ser depurada. ¿Cuál es la mejor manera de hacer esto en Python 2?Envolver excepciones en Python

Respuesta

24

La forma más sencilla sería volver a subir con el objeto de trazado anterior. El siguiente ejemplo muestra lo siguiente:

import sys 

def a(): 
    def b(): 
     raise AssertionError("1") 
    b() 

try: 
    a() 
except AssertionError: # some specific exception you want to wrap 
    trace = sys.exc_info()[2] 
    raise Exception("error description"), None, trace 

Consulte la documentación de la raise statement para los detalles de los tres parámetros. Mi ejemplo imprimiría:

Traceback (most recent call last): 
    File "C:\...\test.py", line 9, in <module> 
    a() 
    File "C:\...\test.py", line 6, in a 
    b() 
    File "C:\...\test.py", line 5, in b 
    raise AssertionError("1") 
Exception: error description 

Para completar, en Python 3 que tendría que utilizar el raise MyException(...) from esyntax.

+1

'raise Exception (" error description "), None, trace' tiene el efecto secundario de perder el mensaje de error original. Alguien sabe una forma de evitar esto? –

+1

Terminé usando el mensaje de la excepción original y lo concateno en el nuevo mensaje. –

+2

Lo hago así: 'raise Exception (" descripción de error \ nCaused by: {}: {} ". Format (tipo (e) .__ name__, str (e))), None, sys.exc_info() [2 ] ' –

1

Esta respuesta es probablemente un poco tarde, pero puede ajustar la función en un python decorator.

Aquí hay un simple cheatsheet sobre cómo diferentes decoradores.

Aquí hay algunos ejemplos de código de cómo hacer esto. Simplemente cambie el decorator para detectar diferentes errores de las diferentes maneras que necesita.

def decorator(wrapped_function): 
    def _wrapper(*args, **kwargs): 
     try: 
      # do something before the function call 
      result = wrapped_function(*args, **kwargs) 
      # do something after the function call 
     except TypeError: 
      print("TypeError") 
     except IndexError: 
      print("IndexError") 
     # return result 
    return _wrapper 


@decorator 
def type_error(): 
    return 1/'a' 

@decorator 
def index_error(): 
    return ['foo', 'bar'][5] 


type_error() 
index_error() 
Cuestiones relacionadas