using System; using System.Linq; using System.Runtime.ExceptionServices; using System.Threading; namespace Swan { /// /// Provides extension methods for . /// public static class ExceptionExtensions { /// /// Returns a value that tells whether an is of a type that /// we better not catch and ignore. /// /// The exception being thrown. /// if is a critical exception; /// otherwise, . public static bool IsCriticalException(this Exception @this) => @this.IsCriticalExceptionCore() || (@this.InnerException?.IsCriticalException() ?? false) || (@this is AggregateException aggregateException && aggregateException.InnerExceptions.Any(e => e.IsCriticalException())); /// /// Returns a value that tells whether an is of a type that /// will likely cause application failure. /// /// The exception being thrown. /// if is a fatal exception; /// otherwise, . public static bool IsFatalException(this Exception @this) => @this.IsFatalExceptionCore() || (@this.InnerException?.IsFatalException() ?? false) || (@this is AggregateException aggregateException && aggregateException.InnerExceptions.Any(e => e.IsFatalException())); /// /// Rethrows an already-thrown exception, preserving the stack trace of the original throw. /// This method does not return; its return type is an exception type so it can be used /// with throw semantics, e.g.: throw ex.RethrowPreservingStackTrace();, /// to let static code analysis tools that it throws instead of returning. /// /// The exception to rethrow. /// This method should never return; if it does, it is an indication of an internal error, /// so it returns an instance of . public static InternalErrorException RethrowPreservingStackTrace(this Exception @this) { ExceptionDispatchInfo.Capture(@this).Throw(); return SelfCheck.Failure("Reached unreachable code."); } private static bool IsCriticalExceptionCore(this Exception @this) => IsFatalExceptionCore(@this) || @this is AppDomainUnloadedException || @this is BadImageFormatException || @this is CannotUnloadAppDomainException || @this is InvalidProgramException || @this is NullReferenceException; private static bool IsFatalExceptionCore(this Exception @this) => @this is StackOverflowException || @this is OutOfMemoryException || @this is ThreadAbortException || @this is AccessViolationException; } }