dotnet / dotnet/dotnet-api-docs
Document stored exceptions
- Dominant language
- C#
- Stars
- 949
- Forks
- 1.7k
- Avg merge
- 3d 27m
- Merged PRs (30d)
- 49
Description
This issue is to discuss if and how to document "stored exceptions", that is, exceptions that are stored in the returned object by Task-returning methods.
With async methods, and more generally Task-returning methods, a majority of exceptions don't emerge synchronously from the call. Rather, any exception gets stored into the returned Task, and then later asking that Task for the exception (via await'ing it, .Wait()'ing it, accessing its .Exception), etc., will surface the exception. If you have a method:
```C#
public static async Task MethodAsync()
{
await Task.Yield();
throw new FormatException();
}
```
and you call it as:
```C#
Task t = MethodAsync();
```
the call to MethodAsync will never throw a `FormatException`. Rather, such an exception may emerge when you later await the task, e.g.
```C#
await t; // throws FormatException
t.GetResult().GetAwaiter(); // throws FormatException
t.Wait(); // throws an AggregateException wrapping FormatException
Exception e = Task.Exception; // returns an AggregateException wrapping FormatException
...
```
Historically, then, we haven't documented FormatException as an exception thrown out of MethodAsync, because technically it's not. Of course, in the 95% use case where a developer does:
```C#
await MethodAsync();
```
the distinction is irrelevant, as it's not directly observable whether the exception was thrown from MethodAsync or by awaiting the task it returned.
_Originally posted by @stephentoub in https://github.com/dotnet/dotnet-api-docs/issues/7692#issuecomment-1034151896_
Contributor guide
Assessment
This issue has not been assessed yet.