Skip to content

Consider usage of ExceptionDispatchInfo instead of BubbleExceptionContainer #124

@jl0pd

Description

@jl0pd

Current implementation with BubbleExceptionContainer have issue of changing original stacktrace.

Consider following code. Semantically it's identical to current behavior - if exception is throw, store it to some field and throw it elsewhere.

void ThrowSomeException() => throw new InvalidOperationException();

void StoreAndThrowExample()
{
    try
    {
        try
        {
            ThrowSomeException();
        }
        catch (Exception ex)
        {
            var storedEx = ex;
            throw ex;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

Result of invoking StoreAndThrowExample is

System.InvalidOperationException: Operation is not valid due to the current state of the object.
   at Program.<<Main>$>g__StoreAndThrowExample|0_2()

Notice that original source is not listed in stacktrace.

Now look at this method that uses ExceptionDispatchInfo:

void ExceptionDispatchInfoExample()
{
    try
    {
        try
        {
            ThrowSomeException();
        }
        catch (Exception ex)
        {
            var exInfo = ExceptionDispatchInfo.Capture(ex);
            exInfo.Throw();
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

which produces following stacktrace:

System.InvalidOperationException: Operation is not valid due to the current state of the object.
   at Program.<<Main>$>g__ThrowSomeException|0_0()
   at Program.<<Main>$>g__ExceptionDispatchInfoExample|0_1()
--- End of stack trace from previous location ---
   at Program.<<Main>$>g__ExceptionDispatchInfoExample|0_1()

This approach is used in async-await

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions