ExceptionHelper
ExceptionHelper provides static methods for working with exceptions
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Text;
namespace NUnit.Framework.Internal
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public static class ExceptionHelper
{
[DoesNotReturn]
public static void Rethrow(Exception exception)
{
ExceptionDispatchInfo.Capture(exception).Throw();
}
public static string BuildMessage(Exception exception, bool excludeExceptionNames = false)
{
Guard.ArgumentNotNull(exception, "exception");
StringBuilder stringBuilder = new StringBuilder();
if (!excludeExceptionNames)
stringBuilder.AppendFormat("{0} : ", exception.GetType());
stringBuilder.Append(GetExceptionMessage(exception));
AppendExceptionDataContents(exception, stringBuilder);
foreach (Exception item in FlattenExceptionHierarchy(exception)) {
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" ----> ");
if (!excludeExceptionNames)
stringBuilder.AppendFormat("{0} : ", item.GetType());
stringBuilder.Append(GetExceptionMessage(item));
AppendExceptionDataContents(item, stringBuilder);
}
return stringBuilder.ToString();
}
public static string BuildStackTrace(Exception exception)
{
StringBuilder stringBuilder = new StringBuilder(exception.GetStackTraceWithoutThrowing());
foreach (Exception item in FlattenExceptionHierarchy(exception)) {
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append("--");
stringBuilder.Append(item.GetType().Name);
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(item.GetStackTraceWithoutThrowing());
}
return stringBuilder.ToString();
}
private static string GetExceptionMessage(Exception ex)
{
string messageWithoutThrowing = ex.GetMessageWithoutThrowing();
if (string.IsNullOrEmpty(messageWithoutThrowing)) {
FileNotFoundException ex2 = ex as FileNotFoundException;
if (ex2 == null)
return "No message provided";
return "Could not load assembly. File not found: " + ex2.FileName;
}
return messageWithoutThrowing;
}
private static void AppendExceptionDataContents(Exception ex, StringBuilder sb)
{
Result<IDictionary> dataWithoutThrowing = ex.GetDataWithoutThrowing();
if (dataWithoutThrowing.IsError(out string message)) {
sb.AppendLine();
sb.Append(message);
} else {
IDictionary value = dataWithoutThrowing.Value;
if (value.Count != 0) {
sb.AppendLine();
sb.Append("Data:");
IDictionaryEnumerator enumerator = value.GetEnumerator();
try {
while (enumerator.MoveNext()) {
DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator.Current;
sb.AppendLine();
sb.AppendFormat(" {0}: {1}", dictionaryEntry.Key, dictionaryEntry.Value?.ToString() ?? "<null>");
}
} finally {
(enumerator as IDisposable)?.Dispose();
}
}
}
}
private static List<Exception> FlattenExceptionHierarchy(Exception exception)
{
List<Exception> list = new List<Exception>();
ReflectionTypeLoadException ex = exception as ReflectionTypeLoadException;
if (ex != null) {
Exception[] loaderExceptions = ex.LoaderExceptions;
foreach (Exception ex2 in loaderExceptions) {
if (ex2 != null)
list.Add(exception);
}
Exception[] loaderExceptions2 = ex.LoaderExceptions;
foreach (Exception ex3 in loaderExceptions2) {
if (ex3 != null)
list.AddRange(FlattenExceptionHierarchy(ex3));
}
}
AggregateException ex4 = exception as AggregateException;
if (ex4 != null) {
list.AddRange(ex4.InnerExceptions);
{
foreach (Exception innerException in ex4.InnerExceptions) {
list.AddRange(FlattenExceptionHierarchy(innerException));
}
return list;
}
}
if (exception.InnerException != null) {
list.Add(exception.InnerException);
list.AddRange(FlattenExceptionHierarchy(exception.InnerException));
}
return list;
}
[return: System.Runtime.CompilerServices.Nullable(2)]
internal static Exception RecordException(Delegate parameterlessDelegate, string parameterName)
{
Guard.ArgumentNotNull(parameterlessDelegate, parameterName);
MethodInfo method = parameterlessDelegate.GetType().GetMethod("Invoke");
Guard.ArgumentValid((object)method != null && method.GetParameters().Length == 0, "The actual value must be a parameterless delegate but was " + parameterlessDelegate.GetType().Name + ".", parameterName);
Guard.ArgumentNotAsyncVoid(parameterlessDelegate, parameterName);
using (new TestExecutionContext.IsolatedContext()) {
if (!AsyncToSyncAdapter.IsAsyncOperation(parameterlessDelegate))
try {
parameterlessDelegate.DynamicInvokeWithTransparentExceptions();
} catch (Exception result) {
return result;
}
else
try {
AsyncToSyncAdapter.Await((Func<object>)parameterlessDelegate.DynamicInvokeWithTransparentExceptions);
} catch (Exception result2) {
return result2;
}
}
return null;
}
public static Exception Unwrap(this Exception exception)
{
NUnitException ex = exception as NUnitException;
if (ex != null && ex.InnerException != null)
exception = ex.InnerException;
while (true) {
TargetInvocationException ex2 = exception as TargetInvocationException;
if (ex2 == null || ex2.InnerException == null)
break;
exception = ex2.InnerException;
}
return exception;
}
}
}