20

If I raise an Exception in Python, here's what I get:

raise Exception("Hello world")
Traceback (most recent call last):

  File "<ipython-input-24-dd3f3f45afbe>", line 1, in <module>
    raise Exception("Hello world")

Exception: Hello world

Note the last line that says Exception: Hello world. Given an Exception (foo = Exception("Hello world")), how can I produce text like this? None of the following work:

str(foo)
Out[27]: 'Hello world'

repr(foo)
Out[28]: "Exception('Hello world',)"

"{}".format(foo)
Out[29]: 'Hello world'

"{}: {}".format(type(foo), foo)
Out[30]: "<type 'exceptions.Exception'>: Hello world"
kuzzooroo
  • 6,788
  • 11
  • 46
  • 84
  • Why do you need to do this? – OneCricketeer Feb 19 '16 at 06:20
  • 1
    Why not just `'Exception: {}'.format(foo)`? – Anton Protopopov Feb 19 '16 at 06:20
  • 1
    @cricket_007, I'm working in a context in which output written to the console likely won't be seen, so I'd like to catch exception, display it, nicely formatted, in a message box (using [EasyGUI](http://easygui.sourceforge.net/) in my case), and then raise it again. – kuzzooroo Feb 19 '16 at 06:24
  • 1
    @AntonProtopopov, when used in practice the exception will have some more interesting type (say, `KeyError`), and I'd like to display that type rather than just labeling everything an exception. – kuzzooroo Feb 19 '16 at 06:25
  • 3
    You can get the same info python prints with `traceback.format_exc()` called in the exception handler. – tdelaney Feb 19 '16 at 06:31

2 Answers2

17

If your exception object is exc, then:

  • The part before the colon is type(exc).__name__.
  • The part after the colon is str(exc).

So you can just do this:

print('{}: {}'.format(type(exc).__name__, exc))
Kevin
  • 28,963
  • 9
  • 62
  • 81
  • Thanks. It's unfortunate that \_\_name__ doesn't show up in `dir(type(foo))` or I might have found this. – kuzzooroo Feb 19 '16 at 06:29
  • It is documented [here](https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy) (scroll down a bit...) – Kevin Feb 19 '16 at 06:32
13

Making tdelaney's answer formal and demonstrating the difference...

Strings

#test.py
import traceback

try :
    raise TypeError("Wrong Type baby!")

except Exception as e:
    print( "EXCEPTION FORMAT PRINT:\n{}".format( e ) )
    print( "EXCEPTION TRACE  PRINT:\n{}".format( "".join(traceback.format_exception(type(e), e, e.__traceback__))

Resulting console output

EXCEPTION FORMAT PRINT:
Wrong Type baby!
EXCEPTION TRACE  PRINT:
Traceback (most recent call last):
  File "test.py", line 4, in <module>
    raise TypeError("Wrong Type baby!")
TypeError: Wrong Type baby!

Logging

If you're in the context of logging there's also the exception method and exc_info kwarg that will do the formatting for you. We should note that the debug and info level log messages are ignored out on account of the root logger holding warning as its default log level.

# logTest.py
import logging

try :
    raise ValueError("my bad value")
except Exception as e :
    logging.exception( e )
    logging.debug("\n{}\nDEBUG LEVEL EXAMPLE".format('-'*30), exc_info=e)
    logging.info("\n{}\nINFO LEVEL EXAMPLE".format('-'*30), exc_info=e)
    logging.warning("\n{}\nWARNING LEVEL EXAMPLE".format('-'*30), exc_info=e)
    logging.error("\n{}\nERROR LEVEL EXAMPLE".format('-'*30), exc_info=e)

with the resulting console output...

ERROR:root:my bad value
Traceback (most recent call last):
  File "/Users/me/logTest.py", line 5, in <module>
    raise ValueError("my bad value")
ValueError: my bad value
WARNING:root:
------------------------------
WARNING LEVEL EXAMPLE
Traceback (most recent call last):
  File "/Users/me/logTest.py", line 5, in <module>
    raise ValueError("my bad value")
ValueError: my bad value
ERROR:root:
------------------------------
ERROR LEVEL EXAMPLE
Traceback (most recent call last):
  File "/Users/me/logTest.py", line 5, in <module>
    raise ValueError("my bad value")
ValueError: my bad value
jxramos
  • 7,356
  • 6
  • 57
  • 105
  • @Jarrad which version of python 3? I just ran this on 3.7.3 – jxramos Apr 17 '20 at 07:29
  • 1
    The strings bit, not the logging bit. – Jarrad Apr 17 '20 at 13:23
  • Looks like `traceback.format_exc()` [doesn't take the exception as the object](https://docs.python.org/3/library/traceback.html#traceback.format_exc), however `traceback.format_exception()` [does](https://docs.python.org/3/library/traceback.html#traceback.format_exception). Could you update the code example? – Scott H Jun 26 '20 at 23:11
  • @ScottH just got around to this now when I realized yah that example is indeed broken. I'm not sure what version of python it ever worked on. – jxramos Sep 30 '20 at 09:37