Fix for Unobserved NavigationException
in Blazor SSR
#62554
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Prevent rethrowing
NavigationException
in finalizer threadDescription
When a NavigationException is thrown from an async component lifecycle method during Blazor server-side rendering, it can become an unobserved task exception if not properly handled. This happens specifically in circular redirection scenarios, where the exception is thrown and then the task is garbage collected before being properly observed.
The issue manifests as an unhandled exception in the finalizer thread with a stack trace like:
Root Cause
The issue occurs in the
WaitForNonStreamingPendingTasks
method inEndpointHtmlRenderer
, where we await a collection of tasks without properly handling NavigationExceptions that might be thrown from them. When the task is garbage collected before completing, the unobserved exception is rethrown from the finalizer thread.Fix
We've added proper exception handling in
WaitForNonStreamingPendingTasks
to specifically catch, observeNavigationExceptions
and handle navigation when possible.Validation
We added
NavigationException_InAsyncContext_DoesNotBecomeUnobservedTaskException
test that verifies no unobserved exceptions occur when a component causes circular redirections, even with forced garbage collection. We set the AppContext switch to make sure navigation uses the exception-driven flow.Fixes #62167