Python – ¿Enviar correo electrónico cuando se produce una excepción?

Tengo una clase de python con muchos métodos ():

Method1()

Method2()

………..

………..

MethodN()

Todos los métodos, mientras se realizan diferentes tareas, tienen el mismo esquema:

 do something do something else has anything gone wrong? raise an exception 

Quiero poder recibir un correo electrónico cada vez que se produzca una excepción en cualquier parte de la clase.

¿Hay alguna manera fácil de combinar esta lógica en la clase, en lugar de llamar a SendEmail() antes de cada statement de raise Exception ? ¿Cuál es la forma correcta y pythonica de tratar este caso? ¿Puede un controlador de excepciones ‘generalizado’ ser la solución? Me alegraría cualquier idea que pueda tener.

Nota: Aunque esta es una solución simple y obvia para el problema como se indica, la respuesta a continuación es probablemente mejor en la mayoría de los casos.

Si la alternativa es esta:

 if problem_test(): SendEmail() raise Exception 

Entonces, ¿por qué no define un método personalizado de raise_email ?

 def raise_email(self, e): SendEmail() raise e 

como @User dijo antes de que Python tenga logging.handlers.SMTPHandler para enviar un mensaje de error registrado. Utilice el módulo de registro! Anular la clase de excepción para enviar un correo electrónico es una mala idea.

Ejemplo rápido:

 import logging import logging.handlers smtp_handler = logging.handlers.SMTPHandler(mailhost=("smtp.example.com", 25), fromaddr="from@example.com", toaddrs="to@example.com", subject=u"AppName error!") logger = logging.getLogger() logger.addHandler(smtp_handler) try: break except Exception as e: logger.exception('Unhandled Exception') 

Saludos.

Python stdlib ha dedicado clase para hacer lo que quieras. Ver logging.handlers.SMTPHandler

¡Cuidado con el aprendiz de brujo !

Sería mejor registrar esos errores, luego verificar cuándo se envió el último correo electrónico, y si el tiempo es demasiado corto, no envíe otro mensaje porque el ser humano ya estará mirando el archivo de registro. Para muchas cosas, un mensaje por día sería suficiente, pero incluso para cosas críticas del sistema, si ya tuvo una falla, ¿qué podría salir mal si espera dos horas para enviar el próximo correo electrónico?

Si envía un correo electrónico cada dos horas, el número máximo de correos electrónicos por día es 12. Y si se produce un error en cascada (¡lo hará!), Es muy probable que ocurra dentro de un par de horas desde el primer evento de error.

La mayoría de las grandes empresas de redes ofrecen un SLA de 4 horas para corregir una falla, medido desde el momento en que ocurre (porque las fallas en cascada tienden a repetirse) hasta que el cliente está satisfecho de que está solucionado. Si tiene un SLA más estricto, entonces, a menos que sea un servicio de la industria financiera, probablemente esté ofreciendo un nivel de servicio demasiado alto.

Pero si tiene un SLA de 4 horas, entonces me aseguraré de que cualquier correo electrónico enviado dentro de las 2 a 4 horas posteriores al último correo electrónico, debe utilizar todas las opciones posibles para priorizarlo, resaltarlo, etc. Por ejemplo, use el Encienda el encabezado X-Priority y coloque la palabra URGENTE en el asunto para que su cliente de correo pueda mostrarla en letras grandes en negrita.

Algo como esto, tal vez?

 def mailexception(ex): # Be creative. print 'Mailing... NOW!' def pokemontrainer(cls): class Rye(cls): def __getattribute__(self, name): def catcher(func): def caller(*args, **kwargs): try: func(*args, **kwargs) except Exception, e: mailexception(e) raise return caller ref = cls.__getattribute__(self, name) if hasattr(cls, name) and hasattr(getattr(cls, name), '__call__'): return catcher(ref) return Rye @pokemontrainer class Exceptor(object): def toss(self, e): raise e('Incoming salad!') ex = Exceptor() ex.toss(ValueError) 

Gist Link

El truco más importante está aquí si no se pasa el parámetro de seguridad, el valor predeterminado es Ninguno, lo que genera una excepción si está intentando autenticarse con servidores STMP habilitados con TLS/SSL como los servidores STMP de Gmail, Yahoo, Yandex.

Pasamos una tupla vacía para activar smtp.ehlo() para autenticar correctamente con SSL.

 ... if self.secure is not None: smtp.ehlo() smtp.starttls(*self.secure) smtp.ehlo() ... import logging import logging.handlers __author__ = 'Ahmed Şeref GÜNEYSU' def foo(): raise Exception("Foo Bar") def main(): logger = logging.getLogger() logger.addHandler(logging.handlers.SMTPHandler( mailhost=("smtp.mail.yahoo.com", 587), fromaddr="boss@example.com", toaddrs="me@example.com", subject="EXCEPTION", credentials=('smtpuser@example.com', 'MY SECRET PASSWORD'), secure=())) try: foo() except Exception, e: logging.exception(e) if __name__ == '__main__': main() 

Qué tal esto:

 class MyException(Exception): def __init__(self): SendEmail() 

Acabo de hacer una subclase de Exception y enviar el correo electrónico en la Excepción personalizada.

Puede usar un enganche excepto para enviar un correo electrónico cuando no se detecte una excepción.

ver sys.excepthook