• How to get insight in the relations between tracebacks of exceptions in an exception-chain

    From Klaas van Schelven@klaas@vanschelven.com to comp.lang.python on Thu Apr 4 09:04:50 2024
    From Newsgroup: comp.lang.python

    Hi,

    This question is best introduced example-first:

    Consider the following trivial program:

    ```
    class OriginalException(Exception):
    pass


    class AnotherException(Exception):
    pass


    def raise_another_exception():
    raise AnotherException()


    def show_something():
    try:
    raise OriginalException()
    except OriginalException:
    raise_another_exception()


    show_something()
    ```

    running this will dump the following on screen (minus annotations on the Right-Hand-Side):

    ```
    Traceback (most recent call last):
    File "...../stackoverflow_single_complication.py", line 15, in
    show_something t1
    raise OriginalException()
    __main__.OriginalException

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
    File "...../stackoverflow_single_complication.py", line 20, in <module>
    t0
    show_something()
    File "...../stackoverflow_single_complication.py", line 17, in
    show_something t2
    raise_another_exception()
    File "...../stackoverflow_single_complication.py", line 10, in raise_another_exception t3
    raise AnotherException()
    __main__.AnotherException
    ```

    What we see here is first the `OriginalException` with the stackframes
    between the moment that it was raised and the moment it was handled.
    Then we see `AnotherException`, with _all_ a complete traceback from its point-of-raising to the start of the program.

    In itself this is perfectly fine, but a consequence of this way of
    presenting the information is that the stackframes are _not_ laid out on
    the screen in the order in which they were called (and not in the reverse
    order either), as per the annotations _t1_, _t0_, _t2_, _t3_. The path
    leading up to _t1_ is of course the same as the path leading up to _t2_,
    and the creators of Python have chosen to present it only once, in the
    latter case, presumably because that Exception is usually the most
    interesting one, and because it allows one to read the bottom exception bottom-up without loss of information. However, it does leave people that
    want to analyze the `OriginalException` somewhat mystified: what led up to
    it?

    A programmer that wants to understand what led up to _t1_ would need to [mentally] copy all the frames above the point _t2_ to the first stacktrace
    to get a complete view. However, in reality the point _t2_ is, AFAIK, not automatically annotated for you as a special frame, which makes the task of mentally copying the stacktrace much harder.

    Since the point _t2_ is in general "the failing line in the `except`
    block", by cross-referencing the source-code this excercise can usually be completed, but this seems unnecessarily hard.

    **Is it possible to automatically pinpoint _t2_ as the "handling frame"?**

    (The example above is given without some outer exception-handling context;
    I'm perfectly fine with answers that introduce it and then use `traceback`
    or other tools to arrive at the correct answer).

    This is the most trivial case that illustrates the problem; real cases have many more stack frames and thus less clearly illustrate the problem but
    more clearly illustrate the need for (potentially automated) clarification
    of what's happening that this SO question is about.


    regards,
    Klaas


    Previously asked here: https://stackoverflow.com/questions/78270044/how-to-get-insight-in-the-relations-between-tracebacks-of-exceptions-in-an-excep
    --- Synchronet 3.20a-Linux NewsLink 1.114