DEV Community

Cover image for C# ExceptionDispatchInfo Class
Karen Payne
Karen Payne

Posted on

C# ExceptionDispatchInfo Class

Introduction

Learn about the ExceptionDispatchInfo object, which stores the stack trace information and Watson information that an exception contains at the point where it's captured. The exception can then be thrown later, possibly on another thread, by calling ExceptionDispatchInfo.Throw method.

Examples

💡 In these examples, the task is simple: read a file that does not exist here.

Conventional example

The following example does not use an ExceptionDispatchInfo object; instead, it checks whether the file exists before attempting to read it.

Results are returned by deconstructing a tuple.

private static void ReadFile()
{

    var fileName = "nonexistentfile.txt";

    if (File.Exists(fileName))
    {
        var (success, lines, exception) = FileOperations.ReadFile();
    }
    else
    {
        SpectreConsoleHelpers.ErrorPill(Justify.Left, $"File '{fileName}' does not exist.");
        Log.Information("File '{FileName}' does not exist. Called from {Method} method.", 
            fileName, 
            nameof(ReadFile));
    }
}
Enter fullscreen mode Exit fullscreen mode

public class FileOperations
{

   public static (bool success, string[] lines, Exception exception) ReadFile()
{
    try
    {
        var lines = File.ReadAllLines("NonExistingFile.txt");
        return (true, lines, null);
    }
    catch (Exception e)
    {
        Log.Error(e, "An error occurred while reading the file.");
        return (false, Array.Empty<string>(), e);
    }

}
Enter fullscreen mode Exit fullscreen mode
  • Uses a try/catch as the user may not have permissions for read access
  • Logs the exception to a daily log file
  • Returns a tuple
    • Success/failure
    • Contents of the file on successful read operation
    • If an exception is raised, the root exception

ExceptionDispatchInfo example

Here, if a runtime exception is raised ExceptionDispatchInfo.Capture method stores the exception and is return as part of the returning tuple.

public class FileOperations
{
    public static (string[] lines, ExceptionDispatchInfo exceptionDispatchInfo) ReadAllLines()
    {
        string[] lines = null;
        ExceptionDispatchInfo exceptionDispatchInfo = null;
        try
        {
            lines = File.ReadAllLines("NonExistingFile.txt");
        }
        catch (Exception localException)
        {
            exceptionDispatchInfo = ExceptionDispatchInfo.Capture(localException);
        }
        return (lines, exceptionDispatchInfo);
    }

}
Enter fullscreen mode Exit fullscreen mode

Calling code:

private static void HandleFileReadOperation1()
{
    var (lines, exceptionDispatchInfo) = FileOperations.ReadAllLines(); // file does not exist
    if (exceptionDispatchInfo is not null)
    {

        SpectreConsoleHelpers.ErrorPill(Justify.Left, "An error occurred while reading the file:");
        ExceptionHelpers.ColorStandard(exceptionDispatchInfo.SourceException);
        Log.Error(exceptionDispatchInfo.SourceException, "An error occurred while reading the file.");

        if (AnsiConsole.Confirm("Continue with throw?"))
        {
            exceptionDispatchInfo!.Throw();
        }

    }
    else
    {
        foreach (var line in lines)
        {
            Console.WriteLine(line);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Return results in a tuple
    • Lines read if the read operation was successful
      • Display lines
    • ExceptionDispatchInfo instance on a failed read operation
      • Display and log error
      • Ask to throw the captured exception

Source code

Source code

Summary

💡 ExceptionDispatchInfo is to be considered to be simply another tool in a developer's toolbox.

Choosing the right path to follow should never be determined by a class or language feature, but by business requirements.

ExceptionDispatchInfo has been available for a long time, but most developers don't know about it, which is why they're more likely to use it because it's new to them. As stated above, do not force the use of ExceptionDispatchInfo.

Applies

Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10, 11
.NET Framework 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

See also

Exception Handling (C# Programming Guide)

Libraries

  • All operations use SeriLog NuGet package to log runtime issues.
  • Spectre.Console library is used to enhance console output

Top comments (0)