9.11 (Optional) Stack Unwinding and Tracebacks

Each exception object stores information indicating the precise series of function calls that led to the exception. This is helpful when debugging your code. Consider the following function definitions—function1 calls function2 and function2 raises an Exception:

In [1]: def function1():
   ...:     function2()
   ...:

In [2]: def function2():
   ...:     raise Exception('An exception occurred')
   ...:

Calling function1 results in the following traceback. For emphasis, we placed in bold the parts of the traceback indicating the lines of code that led to the exception:

In [3]: function1()
-------------------------------------------------------------------------
Exception                               Traceback (most recent call last)
<ipython-input-3-c0b3cafe2087> in <module>()
----> 1 function1()

<ipython-input-1-a9f4faeeeb0c> in function1()
      1 def function1():
----> 2     function2()
      3

<ipython-input-2-c65e19d6b45b> in function2()
      1 def function2():
----> 2     raise Exception('An exception occurred')

Exception: An exception occurred

Traceback Details

The traceback shows the type of exception that occurred (Exception) followed by the complete function call stack that led to the raise point. The stack’s bottom function call is listed first and the top is last, so the interpreter displays the following text as a reminder:

Traceback (most recent call last)

In this traceback, the following text indicates the bottom of the function-call stack—the function1 call in snippet [3] (indicated by ipython-input-3):

<ipython-input-3-c0b3cafe2087> in <module>()
----> 1 function1()

Next, we see that function1 called function2 from line 2 in snippet [1]:

<ipython-input-1-a9f4faeeeb0c> in function1()
      1 def function1():
----> 2     function2()
      3

Finally, we see the raise point—in this case, line 2 in snippet [2] raised the exception:

<ipython-input-2-c65e19d6b45b> in function2()
      1 def function2():
----> 2     raise Exception('An exception occurred')

Stack Unwinding

In our previous exception-handling examples, the raise point occurred in a try suite, and the exception was handled in one of the try statement’s corresponding except handlers. When an exception is not caught in a given function, stack unwinding occurs. Let’s consider stack unwinding in the context of this example:

  • In function2, the raise statement raises an exception. This is not in a try suite, so function2 terminates, its stack frame is removed from the function-call stack, and control returns to the statement in function1 that called function2.

  • In function1, the statement that called function2 is not in a try suite, so function1 terminates, its stack frame is removed from the function-call stack, and control returns to the statement that called function1—snippet [3] in the IPython session.

  • The call in snippet [3] call is not in a try suite, so that function call terminates. Because the exception was not caught (known as an uncaught exception), IPython displays the traceback, then awaits your next input. If this occurred in a typical script, the script would terminate.10

Tip for Reading Tracebacks

You’ll often call functions and methods that belong to libraries of code you did not write. Sometimes those functions and methods raise exceptions. When reading a traceback, start from the end of the traceback and read the error message first. Then, read upward through the traceback, looking for the first line that indicates code you wrote in your program. Typically, this is the location in your code that led to the exception.

Exceptions in finally Suites

Raising an exception in a finally suite can lead to subtle, hard-to-find problems. If an exception occurs and is not processed by the time the finally suite executes, stack unwinding occurs. If the finally suite raises a new exception that the suite does not catch, the first exception is lost, and the new exception is passed to the next enclosing try statement. For this reason, a finally suite should always enclose in a try statement any code that may raise an exception, so that the exceptions will be processed within that suite.

tick mark Self Check

  1. (Fill-In) An uncaught exception in a function causes      . The function’s stack frame is removed from the function-call stack.
    Answer: stack unwinding.

  2. (True/False) Exceptions always are handled in the function that raises the exception.
    Answer: False. Although it is possible to handle an exception in the function that raises it, normally an exception is handled by a calling function on the function-call stack.

  3. (True/False) Exceptions can be raised only by code in try statements.
    Answer: False. Exceptions can be raised by any code, regardless of whether the code is wrapped in a try statement.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.227.69