5

This is the closest answer I could find on catching multiple exceptions (the correct way), when after a miracle of acquiescence the interpreter allowed the following snippet:

try:
    x = "5" + 3
except NameError and TypeError as e:
    print e

The docs would provide this snippet as well, but nothing like the former:

... except (RuntimeError, TypeError, NameError):
...     pass

So it would be nice to have a second opinion, but my question really comes down to this:

  • How can I not only print the message, but insert at the beginning of the print statement the exact type of error raised. For example I would prefer the first snippet to respond by printing this instead: TypeError: cannot concatenate 'str' and 'int' objects

I feel like it probably is not possible, or easy, given that the interpreter lists only args and message as members of NameError but perhaps that is simply incomplete.

I have tried this myself, but it no longer excepts the errors (I might be misunderstanding isinstance):

try:
    x = "5" + 3
except (NameError, TypeError) as e:
    if isinstance(e, NameError):
        print "NameError: " + e
    elif isinstance(e, TypeError):
        print "TypeError: " + e
    else:
        print e
Community
  • 1
  • 1
Leonardo
  • 1,452
  • 3
  • 15
  • 26

4 Answers4

9

You can catch the errors individually. See this link for more examples: http://docs.python.org/2/tutorial/errors.html#handling-exceptions

Something like the following:

try:
    x = "5" + 3
except TypeError as e:
    print "This is a TypeError"
    print e
except NameError as e:
    print "This is a NameError"
    print e
JRP
  • 979
  • 6
  • 9
8

Others have answered your second question well, so I'll tackle your first one:

except NameError and TypeError as e:

is exactly the same as:

except TypeError as e:

It won't catch NameError. Why? Because NameError is truthy, so and evaluates and returns its second argument, TypeError. Try:

print NameError and TypeError

Yes, the exceptions in an except clause are evaluated at runtime like any other expression. In fact, Python doesn't even require that they be exceptions (however, if they're not, they won't ever catch anything because raise does require exceptions... well, you can use strings but they're deprecated).

For this reason you must provide a tuple of the exceptions to be caught:

except (TypeError, ValueError) as e:

Other forms may be accepted by Python as valid syntax, but probably will not work as you might expect.

kindall
  • 178,883
  • 35
  • 278
  • 309
2

Since minitech has already shown you the best way to do what you want (print type(e).__name__), I'll just cover what you've done wrong.

If e = NameError("BAD, BAD, BAD!"), then print e gives BAD, BAD, BAD!.

However, "My string" + e is not valid because e is not a string. Use print "My string", e, print "My string" + str(e) or print "My string{}".format(e) instead.

Veedrac
  • 58,273
  • 15
  • 112
  • 169
1

Your problem is that you are trying to concat a string with an exception like this

>>> 'foo' + TypeError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'type' objects

The most simple workaround:

>>> 'foo' + str(TypeError)
"foo<type 'exceptions.TypeError'>"
>>> 
  • Thank you for a good explanation, since `print e` is acceptable I got it in my mind it was a string! Not a smart thing to do on my part. – Leonardo Sep 26 '13 at 04:01
  • Why should an exception suddenly turn into a string? Weird idea! –  Sep 26 '13 at 04:04
  • "Prior to Python 1.5, standard exceptions were implemented as strings."(!) Source: _Core Python Programming_, 2nd Edition; Wesley J. Chun; Prentice Hall, 2007; Ch.10.5: _*Exceptions as Strings_. Exclamation mark added. ;) – Edward Sep 26 '13 at 04:57