Eugene
Eugene

Reputation: 93

Raising exception during logging

In Python 3 is there a way to raise exception during logging? I mean, can I somehow configure the standard logging module to raise an exception when logging.error(e) is done?

Upvotes: 3

Views: 336

Answers (2)

Mad Physicist
Mad Physicist

Reputation: 114578

You don't normally log an error by calling logging.error(e). You normally call

logging.error('my message', exc_info=True)

OR

logging.error('my message', exc_info=e)  # Where e is the exception object

That being said, you can extend the Logger class to do this:

from logging import Logger, setLoggerClass
from sys import exc_info

class ErrLogger(Logger):
    def error(msg, *args, **kwargs):
        super().error(msg, *args, **kwargs)
        err = kwargs.get('exc_info')
        if not isintsance(err, Exception):
            _, err, _ = exc_info()
            if err is None:
                err = SomeDefaultError(msg)  # You decide what to raise
        raise err

Now register the new class using the setLoggerClass function:

setLoggerClass(ErrLogger)

Setting a custom logger with a custom error is likely a more reliable method than overriding the module level error, which only operates on the root logger.

The method show here will raise errors in the following order:

  1. An error passed through the exc_info keyword-only argument.
  2. The error currently in the process of being handled.
  3. SomeDefaultError that you designate.

If you want to forego this process, replace everything after super().error(msg, *args, **kwargs) with just raise SomeDefaultError(...).

Upvotes: 2

Thomas Weller
Thomas Weller

Reputation: 59640

Yes, you can replace the method by your own method.

import logging

def except_only(msg, *args, **kwargs):
    raise Exception(msg)
logging.error = except_only     # do not use () here!
logging.error("Log an error")

Problem: you need to remember the original method if you want logging + an exception.

import logging

old_logging_error = logging.error   # do not use () here!
def new_logging_error(msg, *args, **kwargs):
    global old_logging_error
    old_logging_error(msg, *args, **kwargs)
    raise Exception(msg)
logging.error = new_logging_error   # do not use () here!

logging.error("Log an error")

Upvotes: 1

Related Questions