using System;
using System.Reflection;
using JetBrains.Annotations;
namespace Developpez.Dotnet
{
///
/// Fournit des méthodes d'extension pour les exceptions
///
public static class ExceptionExtensions
{
static ExceptionExtensions()
{
_prepForRemoting = CreatePrepForRemotingDelegate();
}
#region PreserveStackTrace
private readonly static Func _prepForRemoting;
///
/// Prépare une exception pour qu'elle puisse être relancée sans perdre
/// la trace de la pile originale.
///
/// L'exception à relancer
/// La même exception, préparée pour être relancée sans perdre la trace de la pile originale.
/// Cette méthode permet notamment de relancer la InnerException d'une exception interceptée, en conservant la trace de la pile d'origine.
/// Cette méthode requiert l'exécution en Full Trust.
public static Exception PreserveStackTrace([NotNull] this Exception exception)
{
exception.CheckArgumentNull("exception");
return _prepForRemoting(exception);
}
private static Func CreatePrepForRemotingDelegate()
{
#if NETFX_CORE
var method = typeof (Exception).GetTypeInfo().GetDeclaredMethod("PrepForRemoting");
// Crée un "open instance delegate" à partir de la méthode d'instance
return (Func)method.CreateDelegate(
typeof(Func), null);
#else
var method = typeof(Exception).GetMethod("PrepForRemoting", BindingFlags.Instance | BindingFlags.NonPublic);
// Crée un "open instance delegate" à partir de la méthode d'instance
return (Func)Delegate.CreateDelegate(
typeof(Func), null, method);
#endif
}
#endregion
#region IsCausedBy
///
/// Indique si une exception est causée, directement ou indirectement, par une
/// exception du type spécifié.
///
/// Type d'exception dont on veut vérifier s'il est la cause de l'exception ex
/// Exception à vérifier
/// true si ex est de type TException ou est causée par une exception de type TException; sinon, false.
public static bool IsCausedBy(this Exception ex)
where TException : Exception
{
var tmp = ex;
while (tmp != null)
{
if (tmp is TException)
return true;
tmp = tmp.InnerException;
}
return false;
}
#endregion
}
}