When a Task throws an exception and stops running, it has faulted. The question is, how do you get the exception that was thrown from the faulted Task?
This depends on if you’re awaiting the Task or not.
This article shows how to handle a faulted Task’s exception in two scenarios: when you’re awaiting the Task and when you’re not awaiting it.
Handling an un-awaited Task’s exception
Let’s say you’re starting a background task and not awaiting it. This task may be doing anything, such as monitoring the file system for changes. When it faults, you want to be able to react. In this example, I am simply logging the root cause exception.
To handle the task’s exception, add a continuation by calling ContinueWith() and specify the TaskContinuationOptions.OnlyOnFaulted option. This means the continuation will only execute if the Task had an exception.
The continuation Task’s exception is an AggregateException. To get the root cause exception, use GetBaseException().
Task.Run(BackgroundTask).ContinueWith(t =>
{
var ex = t.Exception?.GetBaseException();
if (ex != null)
{
Logger.Error($"Task faulted and stopped running. ErrorType={ex.GetType()} ErrorMessage={ex.Message}");
}
},
TaskContinuationOptions.OnlyOnFaulted);
Code language: C# (cs)
I’m purposely throwing an exception in the background Task, and this results in the following output:
Task faulted and stopped running. ErrorType=System.NotFiniteNumberException ErrorMessage=Number encountered was not a finite quantity.
Code language: plaintext (plaintext)
Handling an awaited Task’s exception
If you’re able to await the Task, then it’s far simpler. You can await the Task within a try/catch block. When the Task faults, the framework unwraps the AggregateException, allowing you to deal with the base exception that was thrown.
try
{
await BackgroundTaskAsync();
}
catch (Exception ex)
{
Logger.Error($"Task faulted and stopped running. ErrorType={ex.GetType()} ErrorMessage={ex.Message}");
}
Code language: C# (cs)
When I run this code, I get the following:
Task faulted and stopped running. ErrorType=System.NotFiniteNumberException ErrorMessage=Number encountered was not a finite quantity.
Code language: plaintext (plaintext)