4

Why does the function not raise the exception? It's apparently not caught.

def f():
    try:
        raise Exception
    finally:
        return "ok"

print(f())  # ok
Elazar
  • 20,415
  • 4
  • 46
  • 67
planetp
  • 14,248
  • 20
  • 86
  • 160
  • why [return eats exception](http://stackoverflow.com/questions/517060/return-eats-exception) – Elazar Jun 29 '16 at 09:14
  • What else would you expect? You can either return, or raise an exception, but not both. You explicitly requested a return, so no exception can be raised. – marcelm Jun 29 '16 at 11:02

4 Answers4

7

This is explicitly explained in the documentation:

If an exception occurs in any of the clauses and is not handled, the exception is temporarily saved. The finally clause is executed. [..] If the finally clause executes a return or break statement, the saved exception is discarded

deceze
  • 510,633
  • 85
  • 743
  • 889
4

From the docs:

A finally clause is always executed before leaving the try statement.

@deceze quoted the more relevant part in his answer

The function returns the string in the finally clause and doesn't raise the exception since it returned, and that what gets printed.

If you try to execute:

>>> try:
...     raise Exception
... finally:
...     print('yes')
... 
yes
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception

Then as you can see, "yes" is printed and the exception is thrown after the print statement.

Community
  • 1
  • 1
Maroun
  • 94,125
  • 30
  • 188
  • 241
3

From the documentation:

A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. [...] The finally clause is also executed “on the way out” when any other clause of the try statement is left via a break, continue or return statement.

That mean, in a function the finally clause will always be the one that returns. Even if no exception as occurred:

def f():
    try:
        return 'OK'
    finally:
        return 'Finally'

f() # returns 'Finally'
Cyrbil
  • 6,341
  • 1
  • 24
  • 40
2

The documentation says:

A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. When an exception has occurred in the try clause and has not been handled by an except clause (or it has occurred in a except or else clause), it is re-raised after the finally clause has been executed.

In your case, the exception has not been handled, so should be re-raised after the finally clause, but since you return from the finally clause, the exception is never re-raised.

Holt
  • 36,600
  • 7
  • 92
  • 139