Use [DebuggerDisableUserUnhandledExceptions] by halter73 · Pull Request #57148 · dotnet/aspnetcore (original) (raw)

Doing so would wind up breaking more than once, so I think you don't want to do that

Yes, but my assumption is that the debugger would only break if the exception propagated through user code. In this case, that would mean the exception was thrown from a user-defined exception filter or a filter that called user-defined code. I think the weirdest thing about the logic in the current PR is that the debugger would break out of order with causality seemingly reversed.

  1. The original user-unhandled exception gets processed by the user-defined exception filter which then throws a secondary exception. The debugger hasn't stopped for the original user-unhandled exception yet because we were still waiting to see if any exception filters handle the exception.
  2. We then call Debugger.BreakForUserUnhandledException(ex2) to break for the secondary exception thrown by the user-defined exception filter.
  3. Then right after that, we call Debugger.BreakForUserUnhandledException(ex) with the original exception the triggered the exception filter.

I think this is pretty bad, and I should not have even opened the PR with this behavior. I think any of the following are better options.

Do either of you have a preference for which option we should take? Or know of a better option?

I don't think there will be any user-code frames on the exception stack (or the real stack), when I tried it out, you just get a bunch of non-user code frames in the debugger. We also don't have a link between ex2 and the async user frame that threw

Maybe this is the disconnect. My impression is that Debugger.BreakForUserUnhandledException will only do anything if both of the following conditions are met:

  1. You have "Just my code" enabled and you have not unchecked "Break when this exception type is user-unhandled"
    Test unhandled exception
    or configured the "Additional Actions" in the exception settings to "Continue when unhandled in user code"
    https://learn.microsoft.com/en-us/visualstudio/debugger/managing-exceptions-with-the-debugger?view=vs-2022#BKMK_UserUnhandled
    P.S. the discoverability of disabling this for all exception types just disabling "Just my code" should probably be improved. There's no way I would have considered adding the "Additional Actions" column to exception settings without reading the docs. Can we just have it on by default? There aren't many columns to begin with. Also, it would be nice if I could enable breaking on user-unhandled exceptions even if "Just my code" is disabled.
  2. The exception actually propagates through user code. If there are no user-code frames on the exception stack, I would expect Debugger.BreakForUserUnhandledException to never do anything regardless of how VS was configured because the user never had the opportunity to handle the exception.

Is the exception caught here related to the user-code exception, besides the fact that we're in the exception page middleware?

We don't know if the secondary exception relates to the original exception. It certainly could be related if something about the original exception triggered different behavior in a user-defined filter.

I'm not sure how likely it is that a developer would care about this particular exception, seeing as they didn't throw it.

The developer exception page middleware has no good way of knowing if either exception was thrown from user code. I thought it would be up to the debugger to figure this out. Even the original exceptions from inner middleware that the developer exception page middleware handles may not come from or propagate through user code. The same goes for any secondary exceptions thrown by exception filters.