Skip to content
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

Post mortem debugging of the inner exception in exception chain #1042

Closed
jjyyxx opened this issue Sep 3, 2022 · 10 comments · Fixed by #1057
Closed

Post mortem debugging of the inner exception in exception chain #1042

jjyyxx opened this issue Sep 3, 2022 · 10 comments · Fixed by #1057
Labels
enhancement New feature or request

Comments

@jjyyxx
Copy link

jjyyxx commented Sep 3, 2022

As is suggested in Pdb go to a frame in exception within exception, calling pdb.post_mortem on the __context__ of a chained exception gives a chance to debug the inner exception, and this could be nested. A minimal snippet would be

def fail():
  raise Exception(1)

try:
  try:
    fail()
  except Exception as e:
    raise Exception(2) from e
except Exception as e:
  import pdb
  # pdb.post_mortem(e.__traceback__)
  pdb.post_mortem(e.__context__.__traceback__)

But in vscode, I did not find a way to debug the inner exception from the raise Exception(2) from e line. I wonder whether this feature could be implemented.

@int19h
Copy link
Contributor

int19h commented Sep 6, 2022

To clarify, do you expect to see the stack trace at the point where the original exception was raised? Kinda like what happens when an exception is raised and not caught anywhere?

@int19h int19h added the enhancement New feature or request label Sep 6, 2022
@jjyyxx
Copy link
Author

jjyyxx commented Sep 7, 2022

def fail():
  raise Exception(1)

try:
  fail()
except Exception as e:
  raise Exception(2) from e

Normally, when debugging the above snippet in vscode, the breakpoint will hit on the last line (Uncaught exception). This is already reasonable behavior, but I recently found that it's also possible to debug the inner exception (on the second line).

A chained exception is often used to transform error messages or do some extra logging before exiting (This is an unverified statement). Thus, it's desirable to have support for switching to the inner (maybe more than one) exception.

I'm not familiar with the DAP and not sure if it could be implemented similar to different threads in the stacktrace panel. Also, providing a dropdown menu to select along the exception chain.

P.S.: My current workaround is to avoid chained exception, but reraise the original exception and printing message before reraising.

@int19h
Copy link
Contributor

int19h commented Sep 7, 2022

Looking at the DAP spec, there's "innerException", but it looks like we deliberately don't set it:

# Note: ExceptionDetails actually accepts an 'innerException', but
# when passing it, VSCode is not showing the stack trace at all.

However, this was 2 years ago, so we should revisit and see if it works now.

@int19h int19h self-assigned this Sep 7, 2022
@jjyyxx
Copy link
Author

jjyyxx commented Sep 7, 2022

I might be mistaken, but a simple grep through the vscode repository with "innerExceptions" only shows one occurence which is the definition. I'm not sure whether passing this could take effect.

@int19h
Copy link
Contributor

int19h commented Sep 7, 2022

You're right; looks like this is only supported by VS right now and not by VSCode, so the latter needs a feature request to implement that support (and we'll need to talk about UX at that point).

But in the meantime, we can start supplying it to light up any client that does support it.

@int19h
Copy link
Contributor

int19h commented Sep 7, 2022

Passing "innerException" doesn't break VSCode, although, as expected, it also doesn't do anything useful. However, it is indeed supported by VS, although that just causes it to show both exceptions in the popup.

@int19h int19h removed their assignment Sep 7, 2022
@fabioz
Copy link
Collaborator

fabioz commented Sep 16, 2022

Maybe we could just add the additional frames to the existing frame stack (so, it'd be possible to get to that context regardless of the innerException being set).

I'll take a look at this to check if the final result is reasonable.

@wookayin
Copy link

wookayin commented Oct 2, 2024

#1057 implements a great feature to "show" the stacktrace of chained exception, but I'm not sure if it's easily possible to inspect the frames as we move into some frames of the inner exception. How can I do this?

debugpy gives me: "Unable to find thread for evaluation." when I am trying to evaluate an expression or inspect variables (after jumped to the "Chained Exception" frames)

@rchiodo
Copy link
Contributor

rchiodo commented Oct 2, 2024

I don't think it would be possible to do an eval in the chained frames. That frame is gone and hence there's nowhere to run the evaluation.

In this example, I believe you're talking about evaling the value of say x?

def fail():
  x = 4
  raise Exception(1) # Chained exception generated here

try:
  fail()
except Exception as e:
  raise Exception(2) from e # Breakpoint fires here

@int19h
Copy link
Contributor

int19h commented Oct 3, 2024

The traceback object (accessible via e.__traceback__) should be keeping the frame objects alive, though. This particular error message is because pydevd tries to locate the thread to which the specified frame belongs, and fails since no running thread contains that frame. You can see this happening very early on in on_evaluate_request.

I'm not entirely sure why the eval needs to be done on that thread specifically, but I suspect this has to do with the possibility that it is holding some locks, and thus eval from a different thread might deadlock?

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

Successfully merging a pull request may close this issue.

5 participants