343

If I have that code:

try:
    some_method()
except Exception, e:

How can I get this Exception value (string representation I mean)?

vvvvv
  • 25,404
  • 19
  • 49
  • 81
Frias
  • 10,991
  • 9
  • 33
  • 40

7 Answers7

481

use str

try:
    some_method()
except Exception as e:
    s = str(e)

Also, most exception classes will have an args attribute. Often, args[0] will be an error message.

It should be noted that just using str will return an empty string if there's no error message whereas using repr as pyfunc recommends will at least display the class of the exception. My take is that if you're printing it out, it's for an end user that doesn't care what the class is and just wants an error message.

It really depends on the class of exception that you are dealing with and how it is instantiated. Did you have something in particular in mind?

aaronasterling
  • 68,820
  • 20
  • 127
  • 125
  • I'm printing this to make a report, the str(e) is fine i guess. Thanks a lot – Frias Nov 29 '10 at 21:40
  • 13
    I would prefer to use `e.message` because `args[0]` might not be actually a message. – cedbeu Oct 15 '13 at 10:17
  • 5
    repr(e) is also helpful if you want to get the full exception( e.g. NameError("global name 'variable' is not defined",), instead of "global name 'variable' is not defined" – Ben Morris Feb 12 '15 at 18:39
  • 64
    this answer is dangerous, as it will fail for unicode exceptions like this: `raise Exception(u'jörn')`. The failure is especially bad, because you will never see the actual exception but just a `UnicodeDecodeError`. If you don't know the exception's encoding (and most of the time you don't), you should either work on `repr(e)` or if you really need to, use another try-except block in your exception handling which catches UnicodeDecodeErrors and falls back to `repr(e)`. – Jörn Hees Jun 30 '15 at 17:56
  • 14
    Agree with @JörnHees. I cannot count the number of times that `str` (or even `unicode` or `.format`) has caused bugs due to Unicode handling. If you don't have complete control of the error message contents, ALWAYS use `repr` to avoid unexpected Unicode errors. – Kenny Trytek Aug 03 '15 at 16:14
  • In my case, `e.read()` gave error info that `str(e)` didn't have. Any idea why is that @aaronasterling? – Nam G VU Jul 17 '18 at 07:31
  • Agree with @JörnHees. I was logging the error message and THAT caused an error because I was not using repr. not all exceptions can be str()'d . No problems with repr() so far, its just seems plain better – c8999c 3f964f64 Jul 20 '20 at 08:55
281

Use repr() and The difference between using repr and str

Using repr:

>>> try:
...     print(x)
... except Exception as e:
...     print(repr(e))
... 
NameError("name 'x' is not defined")

Using str:

>>> try:
...     print(x)
... except Exception as e:
...     print(str(e))
... 
name 'x' is not defined
Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
pyfunc
  • 65,343
  • 15
  • 148
  • 136
  • 6
    ah, `repr` is useful thanks, it seems anything else `unicode`, `str`, encoding, ... may raise an exception depending on input. Not quite useful when trying to keep the exception to look, but repr is `exception-safe` it seems – dashesy Apr 09 '15 at 18:30
  • 6
    This is *much* better than any `str()`-like solutions, because it actually includes the type of exception. With `str()` I got `'status'` while with `repr()` I got `KeyError('status')` and I was like "aaaaah, now I understand the error". – jlh Jul 26 '17 at 12:08
48

Even though I realise this is an old question, I'd like to suggest using the traceback module to handle output of the exceptions.

Use traceback.print_exc() to print the current exception to standard error, just like it would be printed if it remained uncaught, or traceback.format_exc() to get the same output as a string. You can pass various arguments to either of those functions if you want to limit the output, or redirect the printing to a file-like object.

Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • 1
    Normally I prefer either str() or repr() for a warning or info entry with sys.stdout.write() when I want to show what happened in the background. But, the traceback can be good for when there's a need to show the full error trace without allowing your program to end. – Harlin Apr 15 '21 at 01:40
34

Another way hasn't been given yet:

try:
    1/0
except Exception, e:
    print e.message

Output:

integer division or modulo by zero

args[0] might actually not be a message.

str(e) might return the string with surrounding quotes and possibly with the leading u if unicode:

'integer division or modulo by zero'

repr(e) gives the full exception representation which is not probably what you want:

"ZeroDivisionError('integer division or modulo by zero',)"

edit

My bad !!! It seems that BaseException.message has been deprecated from 2.6, finally, it definitely seems that there is still not a standardized way to display exception messages. So I guess the best is to do deal with e.args and str(e) depending on your needs (and possibly e.message if the lib you are using is relying on that mechanism).

For instance, with pygraphviz, e.message is the only way to display correctly the exception, using str(e) will surround the message with u''.

But with MySQLdb, the proper way to retrieve the message is e.args[1]: e.message is empty, and str(e) will display '(ERR_CODE, "ERR_MSG")'

cedbeu
  • 1,919
  • 14
  • 24
6

To inspect the error message and do something with it (with Python 3)...

try:
    some_method()
except Exception as e:
    if {value} in e.args:
        {do something}
DanGoodrick
  • 2,818
  • 6
  • 28
  • 52
5

The following worked for me:

import traceback

try:
    some_method()
except Exception as e:
   # Python 3.9 or older
   print("".join(traceback.format_exception_only(type(e), e)).strip())
   # Python 3.10+
   print("".join(traceback.format_exception_only(e)).strip())

If some_method() raises the exception ValueError("asdf"), this prints what you see in tracebacks--minus the traceback: ValueError: asdf.

Here is the documentation on this.

Tim Ludwinski
  • 2,704
  • 30
  • 34
3

For python2, It's better to use e.message to get the exception message, this will avoid possible UnicodeDecodeError. But yes e.message will be empty for some kind of exceptions like OSError, in which case we can add a exc_info=True to our logging function to not miss the error.
For python3, I think it's safe to use str(e).

apporc
  • 870
  • 3
  • 11
  • 23