FooBar
FooBar

Reputation: 16488

Exception that emails stack trace when raised

I'd like to have an exception that always sends an email when raised. As for now, I was planning to put that code into __init():

import sendmail
import configparser


def MailException(BaseException):
    """
    sends mail when initiated
    """
    def __init__(self, message, config=None):
        # Call the base class constructor with the parameters it needs
        BaseException.__init__(message)

        if config is None:
            config = configparser.RawConfigParser()
            config.read('mail.ini')
            config = config['email']

        text = 'exception stack trace + message'

        sendmail.sendMail(text=text, config=config['email'], title='Alert')

I'd explicitly like to have the mail-sending here, instead of in every except-block I create. Hence I wonder how to get the stack trace, the code has to be compatible with Python 2.7.

The only thing I could find was traceback, but that apparently only works within the except: realm - or is there a way to implement it within the Exception class? Any other ideas?

Upvotes: 2

Views: 461

Answers (1)

jonrsharpe
jonrsharpe

Reputation: 122024

Firstly, note that (per the docs) you shouldn't subclass BaseException.

Secondly, rather than implement that logic in the exception itself you could define a new sys.excepthook (see e.g. Python Global Exception Handling), then you get access to the full traceback:

import sys


class MailException(Exception):
    pass


def mailing_except_hook(exctype, value, traceback):
    if exctype == MailException:
        ...  # do your thing here
    else:
        sys.__excepthook__(exctype, value, traceback)

sys.excepthook = mailing_except_hook

Upvotes: 2

Related Questions