Extension methods for the Exception class.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Extensions
{
public static class ExceptionExtensions
{
/// <summary>
/// Gets the original Exception which is most inner Exception.
/// </summary>
/// <param name="self">The Exception</param>
/// <returns>The original Exception</returns>
public static Exception Unwrap(this Exception self)
{
if (self == null)
{
return null;
}
var next = self.GetBaseException();
while (next.InnerException != null)
{
// On mono GetBaseException() doesn't seem to do anything so
// just walk the inner exception chain.
next = next.InnerException;
}
return next;
}
/// <summary>
/// Gets all the error messages.
/// </summary>
/// <param name="self">The Exception</param>
/// <note>
/// The most inner self message is first in the list, and
/// the most outer self message is last in the list
/// </note>
/// <returns>IEnumerable of message</returns>
public static IEnumerable<string> Messages(this Exception self)
{
return self != null
? new List<string>(self.InnerException.Messages()) { self.Message }
: Enumerable.Empty<string>();
}
public static string GetExceptionChain(this Exception self)
{
var message = new StringBuilder(self.Message);
if (self.InnerException != null)
{
message.AppendLine();
message.AppendLine(GetExceptionChain(self.InnerException));
}
return message.ToString();
}
///<summary>
/// Gets all the errors
///</summary>
///<param name="self">The Exception</param>
///<returns>IEnumerable of message</returns>
/// <note>
/// The most inner self is first in the list, and
/// the most outer self is last in the list
/// </note>
public static IEnumerable<Exception> Exceptions(this Exception self)
{
return self != null
? new List<Exception>(self.InnerException.Exceptions()) { self }
: Enumerable.Empty<Exception>();
}
/// <summary>
/// Represents exceptions we should never attempt to catch and ignore.
/// </summary>
/// <param name="exception">The exception being thrown.</param>
/// <returns></returns>
public static bool IsCriticalException(this Exception exception)
{
if (exception == null)
{
throw new ArgumentNullException("exception");
}
return exception.IsFatalException()
|| exception is AppDomainUnloadedException
|| exception is BadImageFormatException
|| exception is CannotUnloadAppDomainException
|| exception is InvalidProgramException
|| exception is NullReferenceException
|| exception is ArgumentException;
}
/// <summary>
/// Represents exceptions we should never attempt to catch and ignore
/// when executing third party plugin code.
/// This is not as extensive as a proposed IsCriticalException method
/// that I want to write for our own code.
/// </summary>
/// <param name="exception">The exception being thrown.</param>
/// <returns></returns>
public static bool IsFatalException(this Exception exception)
{
if (exception == null)
{
throw new ArgumentNullException("exception");
}
return exception is StackOverflowException
|| exception is OutOfMemoryException
|| exception is ThreadAbortException
|| exception is AccessViolationException;
}
public static bool CanRetry(this Exception exception)
{
return !exception.IsCriticalException()
&& !(exception is ObjectDisposedException);
}
}
}