Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sys.excepthook doesn't work in imported modules

I am trying to design a Python program that logs all uncaught exceptions using the logging module. I am doing this by using the sys.excepthook function to override the default exception handling. I noticed that if I run the program directly from the command line, it works fine, but if I try to import the file, it doesn't work. It seems like the sys.excepthook function is unaware of the logging module. Here is an example:

#! /usr/bin/env python2.7
import logging, sys

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.FileHandler("test.log"))

print "outside of exception handler: logger = %s" % logger

def handleException(excType, excValue, traceback):
    #global logger  # this function doesn't work whether or not I include this line
    print "inside exception handler: logger = %s" % logger
    logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))

sys.excepthook = handleException

logger.debug("starting")
asdf    # create an exception

If I run this from the command line (./loggingTest.py), it works fine. The exception gets logged, and I see this output:

outside of exception handler: logger = <logging.RootLogger object at 0x7f2022eab950>
inside exception handler: logger = <logging.RootLogger object at 0x7f2022eab950>

However, if I run the Python interpreter and try to import the file (import loggingTest), it acts strangely. The exception doesn't get logged and I see this:

outside of exception handler: logger = <logging.RootLogger object at 0x7f8ab04f3ad0>
inside exception handler: logger = None
Error in sys.excepthook:
Traceback (most recent call last):
  File "loggingTest.py", line 13, in handleException
    logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))
AttributeError: 'NoneType' object has no attribute 'error'

Original exception was:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "loggingTest.py", line 18, in <module>
    asdf    # create an exception
NameError: name 'asdf' is not defined

I can maybe work around this problem by importing the logging module again within sys.excepthook, but I am still curious: why is this happening?

like image 391
Elias Zamaria Avatar asked Mar 27 '11 19:03

Elias Zamaria


2 Answers

I reported this issue as a bug on the Python bug tracker. So far, someone responded that there is definitely a change between Python 2.7 and 2.7.1 and he thinks this is expected behavior. He suggested something like this to log all exceptions:

def handleException(excType, excValue, traceback, logger=logger):
    logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))

sys.excepthook = handleException
like image 145
Elias Zamaria Avatar answered Oct 15 '22 20:10

Elias Zamaria


I can't reproduce your error, even if it happens in exhook.py. This is exhook.py:

#! /usr/bin/env python2.7
import logging, sys, traceback as tb

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.FileHandler("test.log"))

print "outside of exception handler: logger = %s" % logger

def handleException(excType, excValue, traceback):
    #global logger  # this function doesn't work whether or not I include this line
    tb.print_exception(excType, excValue, traceback)
    print "inside exception handler: logger = %s" % logger
    logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))

sys.excepthook = handleException

raise Exception

Then:

Python 2.7 (r27:82525, Jul  4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import exhook
outside of exception handler: logger = <logging.RootLogger object at 0x02AB0A70>

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "exhook.py", line 18, in <module>
    raise Exception
Exception inside exception handler: logger = <logging.RootLogger object at 0x02AB0A70>

It works just fine. Does this work for you?

like image 41
Jochen Ritzel Avatar answered Oct 15 '22 20:10

Jochen Ritzel