Skip to content

[API Proposal]: Let accessing the instance of Exception (if any) on stack. #89724

Description

@voroninp

Background and motivation

From time to time there's a need to not only check whether stack contains a bubbling up exception, but also to get access to the exception itself.

For example, in Open Telemetry library ExceptionProcessor uses Marshal.GetExceptionPointers to check whether exception is thrown withing the scope of activity.

However, if I don't want `OperationCancelledException' to be treated as an error, I need to have access to the instance of the exception thrown. Currently, there's no such possibility.

API Proposal

namespace System.Runtime.ExceptionServices
{
    public static class ExceptionHandling
    {
        public Exception? CurrentException {get;}
    }
}

This API is managed equivalent of the existing ICorDebugThread::GetCurrentException unmanaged debugger API. throw should set this per-thread property (saving previous value), catch with matching exception should restore the previous value.

API Usage

try
{
    throw new Exception();
}
finally
{
    // Here it is not null;
      Console.WriteLine(AppDomain.CurrentDomain.CurrentException is not null);
}
try
{
    throw new Exception();
}
catch
{
    // Here it is null;
   Console.WriteLine(AppDomain.CurrentDomain.CurrentException is null);
}
finally
{
    // Here it is null;
   Console.WriteLine(AppDomain.CurrentDomain.CurrentException is null);
}
try
{
    throw new Exception();
}
catch
{
    // Here it is null;
   Console.WriteLine(AppDomain.CurrentDomain.CurrentException is null);

   throw;
}
finally
{
    // Here it is not null;
   Console.WriteLine(AppDomain.CurrentDomain.CurrentException is not null);
}

Not sure whether value should propagate with async.

Task CheckMe() => Task.Run(() => Console.WriteLine(AppDomain.CurrentDomain.CurrentException is not null));
try
{
    throw new Exception();
}
finally
{
    // Here it is not null;
    Console.WriteLine(AppDomain.CurrentDomain.CurrentException is not null);

    // will it output true or false? 
    await CheckMe();

    // Here it is not null;
    Console.WriteLine(AppDomain.CurrentDomain.CurrentException is not null);
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions