Redefine scope for S4457

I would like to ask to redefine the scope for S4457.
According the description, the intention is to ensure exceptions are thrown in the synchronous part of an asynchronous method.
So, why complaining about exceptions thrown before the first await?

I would like to see that argument checks at the beginning of a method should be compliant.
Exceptions after first await should be non-compliant.

public async Task MyMethodAsync(Order order)
{
    ArgumentNullException.ThrowIfNull(order); // compliant

    var result = await AnotherAsync(); // here starts the asynchronous part

    if (result.State == foo)
    {
        throw new InvalidOperationException("bar"); // non-compliant
    }
}

Hi,

Could you provide your SonarLint flavor and version to verify that you’re looking at a current implementation of the rule, please?

 
Thx,
Ann

We are using

  • SonarLint for Rider 10.8.1
  • SonarLint for Visual Studio 2022 8.0.0
  • SonarQube Community and Developer 10.6.0
1 Like

Hello @lg2de,

When marking a method asynchronous, the compiler transforms the method into a state machine.
It takes the whole body, making no difference between what could be synchronous and what is not, so in a sense, an async method does not contain any synchronous part.

As mentioned in the rule description, when a method is wrapped by the compiler as such, there is no guarantee it will be executed right away. As a consequence, your parameter validation exception might be raised at an unexpected time. Thus, S4457 complains.

In other words, it is expected to raise in your scenario.

S4457 is specifically about argument validation in an asynchronous method. Other exceptions are completely valid in an asynchronous context.

If you want to know more about how async/await works, I suggest this blog post: How Async/Await Really Works in C#, especially the paragraph about the transformation done by the compiler.

I hope this helps!

Have a nice day.

The exception is thrown synchronously!
But, you are right in the outcome. I missed only one detail in the generated code which catches the exception.

Thanks for you time!

1 Like