In the REPL, I can print the string representation of an exception:
>>> print(str(ValueError))
<class 'ValueError'>
>>> print(ValueError)
<class 'ValueError'>
In this simple code, the value is not printing. What am I missing?
First flavor:
try:
raise ValueError
except Exception as e:
print(str(e))
print('We crashed!')
This just outputs We crashed!
The second flavor outputs the same. What happened to print(str(e))?
Second flavor:
def crash():
raise ValueError
try:
crash()
except Exception as e:
print(str(e))
print('We crashed!')
In the REPL, I can print the string representation of an exception:
>>> print(str(ValueError))
<class 'ValueError'>
No, you're printing the string representation of an exception class. When you do
raise ValueError
ValueError isn't actually the exception object that gets raised. Python implicitly raises ValueError() instead, and the str of that is empty.
It does print the exception message, but you have to look closely:
>>> def crash():
... raise ValueError
>>> try:
... crash()
... except Exception as e:
... print(str(e))
... print('We crashed!')
We crashed!
The empty line in front of "We crashed" is the error message (empty string) you supplied when doing raise ValueError. To have the representation of your exceptions use repr instead of str:
>>> try:
... crash()
... except Exception as e:
... print(repr(e))
... print('We crashed!')
ValueError()
We crashed!
Note that raise ValueError is just a shorthand for raise ValueError() (note the paranthesis).
You're not supplying any args to the instance that is eventually created, there's nothing to print.
Supply the message that will eventually get printed out by initializing and supplying it as an argument:
try:
raise ValueError("What value error?")
except Exception as e:
print(str(e))
print('We crashed!')
What value error?
We crashed!
Also, though I know this is just a demonstration, I am obliged to point out that using Exception as the target in your handlers is bad practice :-)
As in user2357112 's answer in your except block your are trying to print an instance of ValueError not the ValueError class. If you want to print the class try something like below.
try:
raise ValueError
except Exception as e:
print(e.__class__)
print('We crashed!')
Related
Suppose that:
TEF is a try-except-finally block.
an exception is raised from within the try clause of TEF
The finally clause, F of block T contains a return statement
TEF contains an except clause E
an exception e is raised inside of E
How can we catch e from outside of clause F and outside of clause E?
If that was confusing, then some code is shown below:
def e():
out = "hello world"
try:
raise ValueError("my name is Sarah")
except BaseException as exc:
# HOW DO I CATCH THE FIRST OF THE FOLLOWING
# exceptions from outside of this, current,
# except clause?
raise ValueError("secret info it would be good to know")
raise AttributeError
raise type("Hell", (Exception,), dict())()
[0, 1, 2][99999]
class AnythingYouCanThinkOf(Exception):
pass
raise AnythingYouCanThinkOf
out = "definitely not `hello world`"
finally:
return out
print(e())
print("No error!!! wowza!")
The code above prints:
hello world
No error!!! wowza!
If we comment out the line out = "hello world" then we get UnboundLocalError: local variable 'out' referenced before assignment. However, I am still not sure how to recover ValueError("secret info it would be good to know")
Also, if you put almost the same code outside of the function e, you get very different results. Why?
if True:
out = "hello world"
try:
raise ValueError("my name is Bob")
except BaseException as exc:
# HOW DO I CATCH THE FIRST OF THE FOLLOWING
# exceptions from outside of this, current,
# except clause?
raise ValueError("what is this madness?")
class AnythingYouCanThinkOf(Exception):
pass
raise AnythingYouCanThinkOf
out = "definitely not `hello world`"
finally:
print(out)
The above results in unhandled exception ValueError: what is this madness? before, we got No error!!! wowza!
I'm learning about exception handling in python and am a little stumped how exactly the context attribute works, or at least why the code I have written produces the outcome it does.
My understanding is that when an exception,E, is raised implicitly during the handling of another exception,P, the exception's E context attribute will store a reference to P.
So I have set up the following code:
def g():
try: 1/0
except Exception as E:
print('E context', E.__context__)
try: raise Exception
except Exception as J:
print('J context', J.__context__)
try: raise Exception
except Exception as M:
print('M context', M.__context__)
try: raise Exception
except Exception as T:
print('T context', T.__context__)
The output I get is:
E context None
J context division by zero
M context
T context
What I was expecting to see was M context and T context to have references to previous exceptions, but that doesn't seem to be the case. Would appreciate knowing where I am going wrong on my thinking on this.
Since you raised a blank exception, print(M.__context__) outputs an empty string (because str(Exception()) is an empty string).
Consider this:
try:
1/0
except Exception as E:
print('E context', E.__context__)
try:
raise Exception('non blank 1')
except Exception as J:
print('J context', J.__context__)
try:
raise Exception('non blank 2')
except Exception as M:
print('M context', M.__context__)
Outputs
E context None
J context division by zero
M context non blank 1
Let's say I have a function.
def foo(data):
if data:
return data[0]
else:
raise ValueError('data is empty')
def main_foo(..):
ele = foo(data)
Now, i want to catch that exception as one of my friends commented
Please re-raise the errors at main_foo
So does that mean I do something like:
def main_foo( .. ):
try:
ele = foo(data)
except ValueError:
logger.log("exception caught")
If you want to log the occurrence of an exception in main_foo, but let some other function actually handle the exception, do this:
def main_foo():
try:
ele = foo(data)
except ValueError:
logger.log("Exception caught")
raise
This will raise the same exception for the caller of main_foo to deal with.
As an experiment, I tried catching a failed assertion.
try: assert 1==2
except Exception as e: print e
Why is nothing displayed?
>>> try: assert 1==2
... except Exception as e: print type(e)
...
<type 'exceptions.AssertionError'>
or
>>> try: assert 1==2, "They Are Not Equal!!"
... except Exception as e: print e
...
They Are Not Equal!!
as to why: it is calling the __str__ method of the exception when you call print... since you did not put any text there, your text is the empty string... which is what's printed.
I got a code something like this:
try:
do_something()
except (urllib2.URLError, socket.timeout), er:
print something
except Exception, ex:
print "The code failed because", ex, "Please review"
Now, the problem is on executing the above code I am getting following output:
The code failed because Please review
p.s.: The 'ex' should return the name of the exception but its not returning anything. Any idea why?
In reference to #Yuji and #Peter, I tried this code:
try:
try:
print x
except Exception, ex:
print "ex:", ex
raise
except Exception, er:
print "er:", er
And the Output was:
ex: name 'x' is not defined .
er: name 'x' is not defined .
Now, why raise(er) is returning an error? And why it does not in you cases?
Not necessarily - the expectation is not entirely true. The following code prints nothing:
try:
raise BaseException()
except BaseException, ex:
print ex
But this prints "abc":
try:
raise BaseException("abc")
except BaseException, ex:
print ex