ExceptionUtilities
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace Polly.Utils
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
internal static class ExceptionUtilities
{
private static readonly FieldInfo StackTraceString = typeof(Exception).GetField("_stackTraceString", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly Type TraceFormat = typeof(StackTrace).GetNestedType("TraceFormat", BindingFlags.NonPublic);
private static readonly MethodInfo TraceToString = typeof(StackTrace).GetMethod("ToString", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] {
TraceFormat
}, null);
private static readonly object[] TraceToStringArgs = new object[1] {
Enum.GetValues(TraceFormat).GetValue(0)
};
public static T TrySetStackTrace<[System.Runtime.CompilerServices.Nullable(0)] T>(this T exception) where T : Exception
{
if (!string.IsNullOrWhiteSpace(exception.StackTrace))
return exception;
exception.SetStackTrace(new StackTrace());
return exception;
}
private static void SetStackTrace(this Exception target, StackTrace stack)
{
object value = TraceToString.Invoke(stack, TraceToStringArgs);
StackTraceString.SetValue(target, value);
}
}
}