6

I am setting the sys.excepthook so that I can log every exception that occurs. Instead of writing to a log, let's use the following example:

def excepthook(self, type_, value, traceback):
    print "\n"
    print type_
    print value
    print traceback
    print "\n"

sys.excepthook = self.excepthook

Now let's say I create a type error, like so:

print 3 + str(2)

Without being caught, this goes into the excepthook and properly prints out the 3 variables:

<type 'exceptions.TypeError'>
unsupported operand type(s) for +
<traceback object at 0x02BAE800>

What I would like to do, is have it ALSO print out the full Exception that was sent to the excepthook (so, in this case, a TypeException). In other words, I'd like it to also display the following information).

Traceback (most recent call last):
  File "testcidnelite.py", line 13, in <module>
    print 3 + str(2)
TypeError: unsupported operand type(s) for +: 'int' and 'str'

If I add the following line:

raise

it will display the exception properly; however, it will also display an error with the term raise:

Error in sys.excepthook:
Traceback (most recent call last):
  File "C:\psi-test-automation\Selenium\TestMethods2.py", line 145, in  excepthook
    raise
TypeError: exceptions must be old-style classes or derived from BaseException, not NoneType 

Altering it to:

raise type_

Will print out the following error:

Error in sys.excepthook:
Traceback (most recent call last):
  File "C:\psi-test-automation\Selenium\TestMethods2.py", line 145, in excepthook
    raise type_
TypeError

Original exception was:
Traceback (most recent call last):
  File "testcidnelite.py", line 13, in <module>
    print 3 + str(2)
TypeError: unsupported operand type(s) for +: 'int' and 'str'

I want it to print out only the 2nd chunk (the original exception). Is this possible?

user2869231
  • 1,431
  • 5
  • 24
  • 53

2 Answers2

9

You can use Python's traceback module to format an exception.

from traceback import format_exception

def excepthook(self, type_, value, traceback):
    print format_exception(type_, value, traceback)

sys.excepthook = self.excepthook

Check out the official documentation for more information and examples.

Rob Cutmore
  • 447
  • 1
  • 4
  • 8
  • 2
    For printing the properly formatted exception I think the method print_exception works better, as per documentation of the `format_exception`: The return value is a list of strings, each ending in a newline and some containing internal newlines. When these lines are concatenated and printed, exactly the same text is printed as does `print_exception()`. – Maximiliano Guerra Oct 26 '16 at 14:20
0

You can call the system sys.excepthook again.

Example code:

# Created by BaiJiFeiLong@gmail.com at 2022/3/1
import logging
import sys
from sys import excepthook

sys.excepthook = lambda *args: (logging.error("Exception occurred: %s", args[1]), excepthook(*args))
raise RuntimeError("IronChainException")

Example output:

ERROR:root:Exception occurred: IronChainException
Traceback (most recent call last):
  File "/tmp/example.py", line 7, in <module>
    raise RuntimeError("IronChainException")
RuntimeError: IronChainException
BaiJiFeiLong
  • 3,716
  • 1
  • 30
  • 28