Döngü yapmanız ve döngü yapmanız gerekir, döngüyü ayrı bir işleve taşımak daha temizdir.
Bununla başa çıkmak için bir uzatma yöntemi oluşturdum. Exception.InnerException ve AggregateException.InnerExceptions 'ı takip ederek, belirtilen türün tüm iç özel durumlarının bir listesini döndürür.
Benim özel sorunumda, iç istisnaların peşinden gitmek her zamankinden daha karmaşıktı çünkü istisnalar, yansıtma yoluyla çağrılan sınıfların kurucuları tarafından fırlatılıyordu. Yakaladığımız istisna, TargetInvocationException türünde bir InnerException'a sahipti ve gerçekten bakmamız gereken istisnalar ağacın derinliklerine gömülmüştü.
public static class ExceptionExtensions
{
public static IEnumerable<T> innerExceptions<T>(this Exception ex)
where T : Exception
{
var rVal = new List<T>();
Action<Exception> lambda = null;
lambda = (x) =>
{
var xt = x as T;
if (xt != null)
rVal.Add(xt);
if (x.InnerException != null)
lambda(x.InnerException);
var ax = x as AggregateException;
if (ax != null)
{
foreach (var aix in ax.InnerExceptions)
lambda(aix);
}
};
lambda(ex);
return rVal;
}
}
Kullanımı oldukça basittir. Örneğin, bir sorunla karşılaşıp karşılaşmadığımızı bilmek istiyorsanız
catch (Exception ex)
{
var myExes = ex.innerExceptions<MyException>();
if (myExes.Any(x => x.Message.StartsWith("Encountered my specific error")))
{
}
}
LibraryException -> LibraryException -> LibraryException -> MyException
. Benim istisnam her zaman zincirin sonuncusudur ve kendi iç istisnası yoktur.