What happens to my first exception (A
) when the second (B
) is raised in the following code?
class A(Exception): pass
class B(Except
I believe all the ingredients to answer your question(s) are already in the existing answers. Let me combine and elaborate.
Let me repeat your question's code to provide line number references:
1 class A(Exception): pass
2 class B(Exception): pass
3
4 try:
5 try:
6 raise A('first')
7 finally:
8 raise B('second')
9 except X as c:
10 print(c)
So to answer your questions:
Your first exception A
is raised in line 6. The finally
clause in line 7 is always executed as soon as the try
block (lines 5-6) is left, regardless if it is left because of successful completion or because of a raised exception.
While the finally
clause is being executed, line 8 raises another exception B
. As Lennart and Ignazio have pointed out, only one exception, the one that is most recently being raised, can be kept track of. So as soon as B
is raised, the overall try
block (lines 4-8) is quit and the exception B
is being caught by the except
statement in line 9 if it matches (if X
is B
).
Hopefully this is clear now from my explanation of 1. You could catch the inner/lower/first exception, though. To merge in Lennart's answer, slightly modified, here's how to catch both:
class A(Exception): pass
class B(Exception): pass
try:
try:
raise A('first')
except A as e:
raise B('second', e)
except Exception as c:
print(c)
The output is:
('second', A('first',))
In Lennart's example the solution to this question is the line except A as e
where the inner/lower/first exception is being caught and stored in variable e
.
As a general gut-feeling of when to catch exceptions, when to ignore them, and when to re-raise, maybe this question and Alex Martelli's answer help.