Skip to content

Conversation

@ernest-koguc
Copy link

Add error message when invoking async methods synchronously in JSInterop

  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

Added error message indicating root cause issue when tyring to invoke async method synchronously through js interop.

Description

This pull request updates the DotNetDispatcher in JSInterop to indicate root issue when asynchronous .NET methods are invoked synchronously from JavaScript. It introduces a runtime check that throws an exception if an async method is invoked synchronously. The changes also add a targeted unit test to verify this behavior.

  • Added a check in DotNetDispatcher.InvokeSynchronously to throw an InvalidOperationException if an async method is invoked synchronously, guiding users to use BeginInvokeDotNet for async methods.
  • Introduced the helper method IsAsyncMethod using the AsyncStateMachineAttribute to reliably detect async methods.
  • Updated method signatures and call sites to pass an isAsyncContext flag, distinguishing between sync and async invocation contexts. This is needed because InvokeSynchronously is used by both sync and async version. [1] [2] [3]
  • Added System.Runtime.CompilerServices import to support async method detection.
    Added a unit test CannotInvokeAsyncMethodSynchronously in DotNetDispatcherTest.cs to verify that attempting to invoke an async method synchronously throws the correct exception and message.

Fixes #46811

Copilot AI review requested due to automatic review settings November 7, 2025 11:35
@ernest-koguc ernest-koguc requested a review from a team as a code owner November 7, 2025 11:35
@github-actions github-actions bot added the needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically label Nov 7, 2025
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Nov 7, 2025
@dotnet-policy-service
Copy link
Contributor

Thanks for your PR, @@ernest-koguc. Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@ernest-koguc
Copy link
Author

@dotnet-policy-service agree

@pavelsavara
Copy link
Member

ideally this would be roslyn analyzer, not runtime change

Copy link
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 adds validation to prevent synchronous invocation of asynchronous JSInvokable methods. The change detects when an async method is called through the synchronous DotNetDispatcher.Invoke path and throws a helpful error message directing users to use BeginInvokeDotNet instead.

  • Introduces async method detection using AsyncStateMachineAttribute
  • Updates InvokeSynchronously to accept an isAsyncContext parameter to distinguish between sync and async invocation paths
  • Adds validation that throws InvalidOperationException when attempting to invoke async methods synchronously

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
DotNetDispatcher.cs Adds IsAsyncMethod helper and async/sync context validation to prevent misuse of async methods in synchronous invocation paths
DotNetDispatcherTest.cs Adds test case CannotInvokeAsyncMethodSynchronously to verify the new validation behavior


Assert.Equal($"The method 'InvokableAsyncMethod' cannot be invoked synchronously because it is asynchronous. Use '{nameof(DotNetDispatcher.BeginInvokeDotNet)}' instead.", ex.Message);
}
internal class SomeInteralType
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

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

Corrected spelling of 'SomeInteralType' to 'SomeInternalType'.

Suggested change
internal class SomeInteralType
internal class SomeInternalType

Copilot uses AI. Check for mistakes.
@pavelsavara pavelsavara added the area-blazor Includes: Blazor, Razor Components label Nov 7, 2025
@martincostello martincostello removed the needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically label Nov 7, 2025
@ernest-koguc
Copy link
Author

ideally this would be roslyn analyzer, not runtime change

But then it would be a change in dotnet/razor repo right? Should I close this one then?

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 community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Calling Asynchronous .NET JS Interop Method Synchronously from JS Produces Misleading Error Message

3 participants