Reputation: 910
Right now, I catch the exception in the except Exception:
clause, and do print(exception)
. The result provides no information since it always prints <class 'Exception'>
. I knew this used to work in python 2, but how do I do it in python3?
Upvotes: 71
Views: 163167
Reputation: 809
You can do:
with self.assertRaisesMessage(ValueError, 'invalid literal for int()'):
int('a')
Upvotes: -1
Reputation: 1767
I'm guessing that you need to assign the Exception
to a variable. As shown in the Python 3 tutorial:
def fails():
x = 1 / 0
try:
fails()
except Exception as ex:
print(ex)
To give a brief explanation, as
is a pseudo-assignment keyword used in certain compound statements to assign or alias the preceding statement to a variable.
In this case, as
assigns the caught exception to a variable allowing for information about the exception to stored and used later, instead of needing to be dealt with immediately.
(This is discussed in detail in the Python 3 Language Reference: The try
Statement.)
There are other compound statements that use as
. The first is the with
statement:
@contextmanager
def opening(filename):
f = open(filename)
try:
yield f
finally:
f.close()
with opening(filename) as f:
# ...read data from f...
Here, with
statements are used to wrap the execution of a block with methods defined by context managers. This functions like an extended try...except...finally
statement in a neat generator package, and the as
statement assigns the generator-produced result from the context manager to a variable for extended use.
(This is discussed in detail in the Python 3 Language Reference: The with
Statement.)
As of Python 3.10, match
statements also use as
:
from random import randint
match randint(0, 2):
case 0|1 as low:
print(f"{low} is a low number")
case _:
print("not a low number")
match
statements take an expression (in this case, randint(0, 2)
) and compare its value to each case
branch one at a time until one of them succeeds, at which point it executes that branch's block. In a case
branch, as
can be used to assign the value of the branch to a variable if that branch succeeds. If it doesn't succeed, it is not bound.
(The match
statement is covered by the tutorial and discussed in detail in the Python 3 Language Reference: match
Statements.)
Finally, as
can be used when importing modules, to alias a module to a different (usually shorter) name:
import foo.bar.baz as fbb
This is discussed in detail in the Python 3 Language Reference: The import
Statement.
Upvotes: 113
Reputation: 57504
Don't use print(e), since that won't print a stack trace, which is a nightmare for debugging. traceback.print_exception is what you're looking for:
import traceback
try:
assert False
except Exception as e:
traceback.print_exception(e)
Upvotes: 1
Reputation: 10090
Try
try:
print(undefined_var)
except Exception as e:
print(e)
this will print the representation given by e.__str__()
:
"name 'undefined_var' is not defined"
you can also use:
print(repr(e))
which will include the Exception class name:
"NameError("name 'undefined_var' is not defined",)"
Upvotes: 21
Reputation: 3125
[In Python3]
Let's say you want to handle an IndexError
and print the traceback, you can do the following:
from traceback import print_tb
empty_list = []
try:
x = empty_list[100]
except IndexError as index_error:
print_tb(index_error.__traceback__)
Note: You can use the format_tb
function instead of print_tb
to get the traceback as a string for logging purposes.
Hope this helps.
Upvotes: 1
Reputation: 316
Although if you want a code that is compatible with both python2 and python3 you can use this:
import logging
try:
1/0
except Exception as e:
if hasattr(e, 'message'):
logging.warning('python2')
logging.error(e.message)
else:
logging.warning('python3')
logging.error(e)
Upvotes: 2
Reputation: 3328
Here is the way I like that prints out all of the error stack.
import logging
try:
1 / 0
except Exception as _e:
# any one of the follows:
# print(logging.traceback.format_exc())
logging.error(logging.traceback.format_exc())
The output looks as the follows:
ERROR:root:Traceback (most recent call last):
File "/PATH-TO-YOUR/filename.py", line 4, in <module>
1 / 0
ZeroDivisionError: division by zero
LOGGING_FORMAT
:
LOGGING_FORMAT = '%(asctime)s\n File "%(pathname)s", line %(lineno)d\n %(levelname)s [%(message)s]'
Upvotes: 5
Reputation: 19
I've use this :
except (socket.timeout, KeyboardInterrupt) as e:
logging.debug("Exception : {}".format(str(e.__str__).split(" ")[3]))
break
Let me know if it does not work for you !!
Upvotes: 0
Reputation: 489
These are the changes since python 2:
try:
1 / 0
except Exception as e: # (as opposed to except Exception, e:)
# ^ that will just look for two classes, Exception and e
# for the repr
print(repr(e))
# for just the message, or str(e), since print calls str under the hood
print(e)
# the arguments that the exception has been called with.
# the first one is usually the message. (OSError is different, though)
print(e.args)
You can look into the standard library module traceback for fancier stuff.
Upvotes: 31