Intereting Posts
ExtractAssociatedIcon возвращает null Почему я не могу использовать Type.GetType () в дженериках? C # – почему гистограмма не работает в Excel 2016? Сколько дней, чтобы добавить для “полумесячных” Удаление объекта XDocument Почему Control.FromHandle (IntPtr) возвращает null в одном подключенном процессе и возвращает действительный объект «Form»? в другом подключенном процессе? Построить VS2017 проект с сервером сборки TFS 2012 Необходимость ClassInterfaceType.None? Как получить диаграмму зависимостей между моими проектами C # Как удалить самые старые строки в файле при использовании FileStream и StreamWriter? Использование расширений: взвешивание плюсов и минусов Функция для сокращения пути к файлу для более удобного чтения Как я могу изменить этот код StringBuilder-to-XML на LINQ-to-XML? Связь между двумя приложениями winform с использованием WCF? Преимущество использования CustomAttributes vs GetCustomAttributes ()

Правильный способ найти самое внутреннее исключение?

Я работаю с некоторыми classами, которые при метании имеют относительно глубокое дерево InnerException. Я бы хотел войти в систему и действовать по самому сокровенному исключению, которое имеет реальную причину проблемы.

В настоящее время я использую нечто похожее

public static Exception getInnermostException(Exception e) { while (e.InnerException != null) { e = e.InnerException; } return e; } 

Это правильный способ обработки деревьев исключений?

Я думаю, вы можете получить самое внутреннее исключение, используя следующий код:

 public static Exception getInnermostException(Exception e) { return e.GetBaseException(); } 

Вы можете использовать метод GetBaseException . Очень быстрый пример:

 try { try { throw new ArgumentException("Innermost exception"); } catch (Exception ex) { throw new Exception("Wrapper 1",ex); } } catch (Exception ex) { // Writes out the ArgumentException details Console.WriteLine(ex.GetBaseException().ToString()); } 

Одним словом, да. Я не могу придумать какой-либо значительно лучший или отличный способ сделать это. Если вы не захотите добавить его как метод расширения вместо этого, но это действительно шесть из одного, полдюжины других.

Существуют исключения, которые могут иметь несколько основных причин (например, AggregateException и ReflectionTypeLoadException ).

Я создал свой собственный class для навигации по дереву, а затем к другим посетителям, чтобы собрать все или только коренные причины. Здесь выводятся примеры. Соответствующий fragment кода ниже.

 public void Accept(ExceptionVisitor visitor) { Read(this.exception, visitor); } private static void Read(Exception ex, ExceptionVisitor visitor) { bool isRoot = ex.InnerException == null; if (isRoot) { visitor.VisitRootCause(ex); } visitor.Visit(ex); visitor.Depth++; bool isAggregateException = TestComplexExceptionType(ex, visitor, aggregateException => aggregateException.InnerExceptions); TestComplexExceptionType(ex, visitor, reflectionTypeLoadException => reflectionTypeLoadException.LoaderExceptions); // aggregate exceptions populate the first element from InnerExceptions, so no need to revisit if (!isRoot && !isAggregateException) { visitor.VisitInnerException(ex.InnerException); Read(ex.InnerException, visitor); } // set the depth back to current context visitor.Depth--; } private static bool TestComplexExceptionType(Exception ex, ExceptionVisitor visitor, Func> siblingEnumerator) where T : Exception { var complexException = ex as T; if (complexException == null) { return false; } visitor.VisitComplexException(ex); foreach (Exception sibling in siblingEnumerator.Invoke(complexException)) { visitor.VisitSiblingInnerException(sibling); Read(sibling, visitor); } return true; }