// Copyright (c) Ben A Adams. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Collections.Generic.Enumerable;
using System.Reflection;
using System.Text;
namespace System.Diagnostics
{
///
public static class ExceptionExtentions
{
private static readonly FieldInfo stackTraceString = typeof(Exception).GetField("_stackTraceString", BindingFlags.Instance | BindingFlags.NonPublic);
private static void SetStackTracesString(this Exception exception, string value)
=> stackTraceString.SetValue(exception, value);
///
/// Demystifies the given and tracks the original stack traces for the whole exception tree.
///
public static T Demystify(this T exception) where T : Exception
{
try
{
var stackTrace = new EnhancedStackTrace(exception);
if (stackTrace.FrameCount > 0)
{
exception.SetStackTracesString(stackTrace.ToString());
}
if (exception is AggregateException aggEx)
{
foreach (var ex in EnumerableIList.Create(aggEx.InnerExceptions))
{
ex.Demystify();
}
}
exception.InnerException?.Demystify();
}
catch
{
// Processing exceptions shouldn't throw exceptions; if it fails
}
return exception;
}
///
/// Gets demystified string representation of the .
///
///
/// method mutates the exception instance that can cause
/// issues if a system relies on the stack trace be in the specific form.
/// Unlike this method is pure. It calls first,
/// computes a demystified string representation and then restores the original state of the exception back.
///
[Contracts.Pure]
public static string ToStringDemystified(this Exception exception)
=> new StringBuilder().AppendDemystified(exception).ToString();
}
}