Skip to content

gh-126935: added handler frame to output of traceback of a chained exception #127021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

blhsing
Copy link
Contributor

@blhsing blhsing commented Nov 19, 2024

When an exception is chained, the traceback of the __context__ of the new exception would be pointing to the handler frame. This PR makes use of this behavior to produce a traceback output with the handler frame noted with the wording (from context) for better traceability. Same goes for a frame raising from a cause, which is noted with the wording (from cause).

For example, the following snippet:

class OriginalException(Exception):
    pass

class AnotherException(Exception):
    pass

def raise_exception():
    raise OriginalException()

def raise_another_exception():
    raise AnotherException()

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

show_something()

would now with this PR produce something like:

Traceback (most recent call last):
  File "test.py", line 15, in show_something
    raise_exception()
  File "test.py", line 8, in raise_exception
    raise OriginalException()
OriginalException

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 19, in <module>
    show_something()
  File "test.py", line 17, in show_something (from context)
    raise_another_exception()
  File "test.py", line 11, in raise_another_exception
    raise AnotherException()
AnotherException

@vanschelven
Copy link

As a clarification, pre-PR the output is as such:

Traceback (most recent call last):
  File "test.py", line 15, in show_something
    raise_exception()
  File "test.py", line 8, in raise_exception
    raise OriginalException()
OriginalException

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 19, in <module>
    show_something()
  File "test.py", line 17, in show_something
    raise_another_exception()
  File "test.py", line 11, in raise_another_exception
    raise AnotherException()
AnotherException

@vanschelven
Copy link

My 2 cents: this is more confusing than the pre-PR situation, because I would look at the bottom of each Exception's individual stack to determine what's being raised for that exception. That no longer works with this PR.

@blhsing
Copy link
Contributor Author

blhsing commented Nov 20, 2024

My 2 cents: this is more confusing than the pre-PR situation, because I would look at the bottom of each Exception's individual stack to determine what's being raised for that exception. That no longer works with this PR.

This was more meant as a demonstration of the idea that the frame of the traceback can be used to identify the handler frame, and I chose an output that added the handler frame to the context stack in order to complete the timeline, but you're absolutely right that the added frame obscures the exception being raised. I've rewritten the PR so that the handler frame is simply formatted with an additional note instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants