-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Open
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Threading.Taskscode-analyzerMarks an issue that suggests a Roslyn analyzerMarks an issue that suggests a Roslyn analyzercode-fixerMarks an issue that suggests a Roslyn code fixerMarks an issue that suggests a Roslyn code fixerhelp wanted[up-for-grabs] Good issue for external contributors[up-for-grabs] Good issue for external contributors
Milestone
Description
Sparked from this question: #70574 (comment)
Exceptions thrown inside methods that return Task or ValueTask should be wrapped by Task.FromException, except if they are ArgumentNullException or ArgumentException.
If the method is marked as async, we could also await the Task.FromException.
Suggested category: Reliability
Suggested level: Warning (Same as CA2007)
Suggested milestone: 8.0
Examples
Method that returns Task
Before
// Task
private Task MyMethodAsync(string arg, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(arg);
if (/* some condition */)
{
throw new InvalidOperationException("Some message");
}
return SomethingAsync(cancellationToken);
}
// async Task
private async Task MyMethodAsync(string arg, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(arg);
if (/* some condition */)
{
throw new InvalidOperationException("Some message");
}
await SomethingAsync(cancellationToken).ConfigureAwait(false);
}After
// Task
private Task MyMethodAsync(string arg, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(arg); // Do not change this
if (/* some condition */)
{
return Task.FromException(new InvalidOperationException("Some message")); // wrap this
}
return SomethingAsync(cancellationToken);
}
// async Task
private Task MyMethodAsync(string arg, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(arg); // Do not change this
if (/* some condition */)
{
// wrap this, await it, but don't add ConfigureAwait(false), that should be added by CA2007 separately
await Task.FromException(new InvalidOperationException("Some message"));
}
await SomethingAsync(cancellationToken).ConfigureAwait(false);
}Method that returns ValueTask
Before
// ValueTask
private ValueTask MyMethodAsync(string arg, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(arg);
if (/* some condition */)
{
throw new InvalidOperationException("Some message");
}
return SomethingAsync(cancellationToken);
}
// async ValueTask
private async ValueTask MyMethodAsync(string arg, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(arg);
if (/* some condition */)
{
throw new InvalidOperationException("Some message");
}
await SomethingAsync(cancellationToken).ConfigureAwait(false);
}After
private ValueTask MyMethodAsync(string arg, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(arg); // Do not change this
if (/* some condition */)
{
return ValueTask.FromException(new InvalidOperationException("Some message")); // wrap this
}
return SomethingAsync(cancellationToken);
}
// async ValueTask
private async ValueTask MyMethodAsync(string arg, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(arg);
if (/* some condition */)
{
// wrap this, await it, but don't add ConfigureAwait(false), that should be added by CA2007 separately
await ValueTask.FromException(new InvalidOperationException("Some message"));
}
await SomethingAsync(cancellationToken).ConfigureAwait(false);
}cc @buyaa-n
xsoheilalizadeh and cremor
Metadata
Metadata
Assignees
Labels
api-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedarea-System.Threading.Taskscode-analyzerMarks an issue that suggests a Roslyn analyzerMarks an issue that suggests a Roslyn analyzercode-fixerMarks an issue that suggests a Roslyn code fixerMarks an issue that suggests a Roslyn code fixerhelp wanted[up-for-grabs] Good issue for external contributors[up-for-grabs] Good issue for external contributors