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
Related
I have the following code structure:
try:
x = function_one(args)
try:
y = function_two(args)
try:
#
# some code where I need x and y
#
except Exception as e::
print("Problem with code above : ", e)
except Exception as e:
print("Problem with function_two : ", e)
#
# some code here
#
except Exception as e:
print("Problem with function_one : ", e)
It works but i was wondering if i can avoid this nested try/exception ?
For example if x is empty and can't be used after, would it be better to put the try / except inside function_one and find a solution to check if i can use x for the rest of the code, and if not, stop the code ?
I could do a if x something but it creates also nested part.
If your exception block is not doing something functional(proceeding with the rest of the code if it even has an error inside), you shouldn't use a nested try-catch block. Instead, you can write more exception blocks. For example,
try:
x = function_one(args)
y = function_two(args)
except Exceptionx as e:
print("Problem with function_one : ", e)
except Exceptiony as e:
print("Problem with function_two : ", e)
The Exceptionx and Exceptiony should be Exception class object and you should know that what kind of exception you would get. You can learn more examples at
https://docs.python.org/3/tutorial/errors.html
If you're only checking a certain block of code with a try\except, you can just wrap that block in the handler:
try:
x = function_one(args)
except Exception as e:
print("Problem with function_one : ", e)
try:
y = function_two(args)
except Exception as e:
print("Problem with function_two : ", e)
try:
#
# some code where I need x and y
#
except Exception as e::
print("Problem with code above : ", e)
try:
#
# some code here
#
except Exception as e::
print("Problem with code above : ", e)
In general, only nest exception blocks if you plan to handle a more specific error in the inner block.
If the reason for the different except blocks is to better understand where the error occurred, you can just wrap the whole block in a single try-except block and print the traceback:
import traceback
try:
x = function_one(args)
y = function_two(args)
except:
traceback.print_exc()
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
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!')
I wrote a crawler to fetch information out of an Q&A website. Since not all the fields are presented in a page all the time, I used multiple try-excepts to handle the situation.
def answerContentExtractor( loginSession, questionLinkQueue , answerContentList) :
while True:
URL = questionLinkQueue.get()
try:
response = loginSession.get(URL,timeout = MAX_WAIT_TIME)
raw_data = response.text
#These fields must exist, or something went wrong...
questionId = re.findall(REGEX,raw_data)[0]
answerId = re.findall(REGEX,raw_data)[0]
title = re.findall(REGEX,raw_data)[0]
except requests.exceptions.Timeout ,IndexError:
print >> sys.stderr, URL + " extraction error..."
questionLinkQueue.task_done()
continue
try:
questionInfo = re.findall(REGEX,raw_data)[0]
except IndexError:
questionInfo = ""
try:
answerContent = re.findall(REGEX,raw_data)[0]
except IndexError:
answerContent = ""
result = {
'questionId' : questionId,
'answerId' : answerId,
'title' : title,
'questionInfo' : questionInfo,
'answerContent': answerContent
}
answerContentList.append(result)
questionLinkQueue.task_done()
And this code, sometimes, may or may not, gives the following exception during runtime:
UnboundLocalError: local variable 'IndexError' referenced before assignment
The line number indicates the error occurs at the second except IndexError:
Thanks everyone for your suggestions, Would love to give the marks that you deserve, too bad I can only mark one as the correct answer...
In Python 2.x, the line
except requests.exceptions.Timeout, IndexError:
is equivalent to
except requests.exceptions.Timeout as IndexError:
Thus, the exception caught by requests.exceptions.Timeout is assigned to IndexError. A simpler example:
try:
true
except NameError, IndexError:
print IndexError
#name 'true' is not defined
To catch multiple exceptions, put the names in parentheses:
except (requests.exceptions.Timeout, IndexError):
Later, an UnboundLocalError can occur because the assignment to IndexError makes it a local variable (shadowing the builtin name):
>>> 'IndexError' in answerContentExtractor.func_code.co_varnames
True
So, if requests.exceptions.Timeout was not raised, IndexError will not have been (incorrectly) defined when the code attempts except IndexError:.
Again, a simpler example:
def func():
try:
func # defined, so the except block doesn't run,
except NameError, IndexError: # so the local `IndexError` isn't assigned
pass
try:
[][1]
except IndexError:
pass
func()
#UnboundLocalError: local variable 'IndexError' referenced before assignment
In 3.x, the problem will occur (after fixing the except syntax, which makes the error more obvious) even if the first exception is caught. This is because the local name IndexError will then be explicitly deld after the first try/except block.
When you say
except requests.exceptions.Timeout ,IndexError:
Python will except requests.exceptions.Timeout error and the error object will be IndexError. It should have been something like this
except (requests.exceptions.Timeout ,IndexError) as e:
except requests.exceptions.Timeout ,IndexError:
means same as except requests.exceptions.Timeout as IndexError
You should use
except (requests.exceptions.Timeout, IndexError):
instead