Skip to content

Catch and discard JSDisconnectedException in IJSObjectReference.DisposeAsync for WebView#66259

Open
Copilot wants to merge 2 commits into
mainfrom
copilot/fix-ijsobjectreference-dispose-exception
Open

Catch and discard JSDisconnectedException in IJSObjectReference.DisposeAsync for WebView#66259
Copilot wants to merge 2 commits into
mainfrom
copilot/fix-ijsobjectreference-dispose-exception

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 10, 2026

When components dispose IJSObjectReference instances during DisposeAsync, a JSDisconnectedException can be thrown if the JS runtime is no longer available (circuit disconnected, WebView navigated away, or WebView disposed). This is a spurious error — the JS side is already gone, so server-side cleanup of the reference is unnecessary.

Description

JSObjectReference.DisposeAsync already catches and discards JSDisconnectedException. This PR extends the same pattern to Blazor WebView:

  • WebViewJSRuntime: Added _disconnected flag + internal MarkAsDisconnected() method. When set, BeginInvokeJS throws JSDisconnectedException immediately (same pattern as RemoteJSRuntime.MarkPermanentlyDisconnected()).

  • PageContext.DisposeAsync: Calls JSRuntime.MarkAsDisconnected() before Renderer.DisposeAsync(), preventing JS interop calls from hanging or throwing during component teardown when the page has navigated away or the WebView is being disposed.

  • Tests: Two new tests verify that the JS runtime is marked disconnected on WebView disposal and on page navigation.

// PageContext.DisposeAsync — before this change, DisposeAsync on a JSObjectReference
// would hang or propagate exceptions when the WebView was already gone
public async ValueTask DisposeAsync()
{
    JSRuntime.MarkAsDisconnected(); // new
    await Renderer.DisposeAsync();
    await _serviceScope.DisposeAsync();
}

Copilot AI changed the title [WIP] Fix IJSObjectReference.Dispose to handle JSDisconnectedException Catch and discard JSDisconnectedException in IJSObjectReference.DisposeAsync for WebView Apr 10, 2026
Copilot AI requested a review from javiercn April 10, 2026 07:33
@github-actions github-actions Bot added the area-blazor Includes: Blazor, Razor Components label Apr 10, 2026
Copilot AI and others added 2 commits May 8, 2026 12:41
@javiercn javiercn marked this pull request as ready for review May 8, 2026 10:41
@javiercn javiercn requested a review from a team as a code owner May 8, 2026 10:41
Copilot AI review requested due to automatic review settings May 8, 2026 10:41
@javiercn javiercn force-pushed the copilot/fix-ijsobjectreference-dispose-exception branch from 31ba024 to 79a0c4d Compare May 8, 2026 10:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves Blazor WebView teardown/navigation behavior by marking the WebView JS runtime as disconnected early, so component disposal (including IJSObjectReference.DisposeAsync) doesn’t attempt JS interop when the WebView/page is already gone.

Changes:

  • Add a disconnected state to WebViewJSRuntime and throw JSDisconnectedException for any JS interop after disconnection.
  • Mark the JS runtime as disconnected at the start of PageContext.DisposeAsync() to prevent interop during renderer/component disposal.
  • Add WebViewManager tests that validate JS interop throws JSDisconnectedException after WebView disposal and after page re-attach (navigation simulation).

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/Components/WebView/WebView/test/WebViewManagerTests.cs Adds tests asserting JS interop throws JSDisconnectedException after disposal/navigation.
src/Components/WebView/WebView/src/WebViewManager.cs Exposes the current PageContext (internal) for test inspection.
src/Components/WebView/WebView/src/Services/WebViewJSRuntime.cs Introduces _disconnected flag + MarkAsDisconnected() and throws JSDisconnectedException when disconnected.
src/Components/WebView/WebView/src/PageContext.cs Marks the JS runtime disconnected before disposing the renderer and scope.

Comment on lines 32 to +35
private PageContext _currentPageContext;
private bool _disposed;

internal PageContext CurrentPageContext => _currentPageContext;
Comment on lines 52 to +56
protected override void BeginInvokeJS(in JSInvocationInfo invocationInfo)
{
if (_disconnected)
{
throw new JSDisconnectedException(
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Change IJSObjectReference.Dispose specifically so that it deals with catching and discarding JSDisconnectedException internally

3 participants