My sys.excepthook dies painfully

Chris Angelico rosuav at gmail.com
Wed Jul 23 03:36:36 EDT 2014


On Wed, Jul 23, 2014 at 5:14 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> Error in sys.excepthook:
> Traceback (most recent call last):
>   File "/home/steve/mylogging.py", line 28, in my_error_handler
>     mylogger.exception(msg)
> AttributeError: 'NoneType' object has no attribute 'exception'
>
> Original exception was:
> Traceback (most recent call last):
>   [...]
>   File "/home/steve/mylogging.py", line 35, in <module>
>     foo
> NameError: name 'foo' is not defined

I was not able to repro this with the 3.5-messy that I have on this
system, nor a clean 3.4.1 from Debian Jessie. It's slightly different:

rosuav at dewey:~$ python3 mylogging.py
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python3.4/logging/__init__.py", line 846, in handle
    self.emit(record)
  File "/usr/lib/python3.4/logging/handlers.py", line 881, in emit
    msg = self.format(record)
  File "/usr/lib/python3.4/logging/__init__.py", line 821, in format
    return fmt.format(record)
  File "/usr/lib/python3.4/logging/__init__.py", line 566, in format
    record.exc_text = self.formatException(record.exc_info)
  File "/usr/lib/python3.4/logging/__init__.py", line 516, in formatException
    traceback.print_exception(ei[0], ei[1], tb, None, sio)
  File "/usr/lib/python3.4/traceback.py", line 169, in print_exception
    for line in _format_exception_iter(etype, value, tb, limit, chain):
  File "/usr/lib/python3.4/traceback.py", line 146, in _format_exception_iter
    for value, tb in values:
  File "/usr/lib/python3.4/traceback.py", line 125, in _iter_chain
    context = exc.__context__
AttributeError: 'NoneType' object has no attribute '__context__'

Original exception was:
Traceback (most recent call last):
  File "mylogging.py", line 24, in <module>
    foo  # Die with uncaught NameError.
NameError: name 'foo' is not defined

(Obviously that's the clean 3.4, but it's the same exception in 3.5.)

>From what I can see, the problem is that sys.exc_info() is returning
None, None, None at this point, and the Logger.exception() method
specifically looks for the currently-being-handled exception. You can
get equivalent functionality with this:

def my_error_handler(type, value, tb):
    msg = "Uncaught %s: %s" % (type, value)
    mylogger.error(msg, exc_info=(type, value, tb))
    sys.__excepthook__(type, value, tb)  # print the traceback to stderr

At least, I think that's correct. It does seem to dump a lot of stuff
into a single line in the log, though.

Can't repro your exact traceback, though, so I don't know what's going on there.

ChrisA



More information about the Python-list mailing list