Find inner exception without using while loop?

When C # throws an exception, it may have an internal exception. What I want to do is get an inner exception, or, in other words, a leaf exception that does not have an inner exception. I can do this in a while loop:

while (e.InnerException != null) { e = e.InnerException; } 

But I was wondering if there was any one liner that I could use for this.

+75
c # exception exception-handling while-loop
Oct. 06 '10 at 20:11
source share
10 answers

Oneliner :)

 while (e.InnerException != null) e = e.InnerException; 

Obviously, you cannot make it easier.

As said in this answer from Glenn McElhoe, this is the only reliable way.

+125
06 Oct '10 at 20:17
source share

I believe that Exception.GetBaseException() does the same thing as these solutions.

Caution: from various comments we found out that this does not always literally do the same thing, and in some cases a recursive / iterative solution will help you move forward. This is usually the innermost exception, which, unfortunately, is inconsistent, due to certain types of exceptions that override the default value. However, if you catch certain types of exceptions and make sure with certainty that they are not strange (for example, AggregateException), then I expect that it will receive a legitimate innermost / earliest exception.

+118
Apr 26 2018-11-11T00:
source share

Looping through InnerExceptions is the only reliable way.

If the caught exception is an AggregateException, then GetBaseException() returns only the innermost AggregateException.

http://msdn.microsoft.com/en-us/library/system.aggregateexception.getbaseexception.aspx

+17
Oct 10 '13 at 15:07
source share

If you don't know how deep inner exceptions are nested, there is no way around looping or recursion.

Of course, you can define an extension method that abstracts this:

 public static class ExceptionExtensions { public static Exception GetInnermostException(this Exception e) { if (e == null) { throw new ArgumentNullException("e"); } while (e.InnerException != null) { e = e.InnerException; } return e; } } 
+12
06 Oct '10 at 20:18
source share

I know this is an old post, but I am surprised that no one suggested GetBaseException() , which is an Exception class method:

 catch (Exception x) { var baseException = x.GetBaseException(); } 

This happens with .NET 1.1. Documentation here: http://msdn.microsoft.com/en-us/library/system.exception.getbaseexception(v=vs.71).aspx

+10
Mar 05 '13 at 8:43
source share

You can use recursion to create a method in some utility class.

 public Exception GetFirstException(Exception ex) { if(ex.InnerException == null) { return ex; } // end case else { return GetFirstException(ex.InnerException); } // recurse } 

Using:

 try { // some code here } catch (Exception ex) { Exception baseException = GetFirstException(ex); } 

Proposed extension method (good idea @dtb)

 public static Exception GetFirstException(this Exception ex) { if(ex.InnerException == null) { return ex; } // end case else { return GetFirstException(ex.InnerException); } // recurse } 

Using:

 try { // some code here } catch (Exception ex) { Exception baseException = ex.GetFirstException(); } 
+1
Oct 06 '10 at 20:17
source share

Sometimes you may have many internal exceptions (many bubble exceptions). In this case, you can do:

 List<Exception> es = new List<Exception>(); while(e.InnerException != null) { es.add(e.InnerException); e = e.InnerException } 
+1
06 Oct '10 at 20:32
source share

Not exactly one line, but close:

  Func<Exception, Exception> last = null; last = e => e.InnerException == null ? e : last(e.InnerException); 
+1
Oct. 06 2018-10-06
source share

Actually it's that simple, you can use Exception.GetBaseException()

 Try //Your code Catch ex As Exception MessageBox.Show(ex.GetBaseException().Message, My.Settings.MsgBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); End Try 
+1
Dec 05
source share

You need to loop, and for this you need to clear it to move the loop into a separate function.

I created an extension method to handle this. It returns a list of all internal exceptions of the specified type, with the exception Exception.InnerException and AggregateException.InnerExceptions.

In my particular problem, the pursuit of internal exceptions was more complicated than usual because the exceptions were thrown by the constructors of classes that were called through reflection. The exception we caught was an InnerException of type TargetInvocationException, and the exceptions that we really looked for were deeply immersed in the tree.

 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; } } 

The use is pretty simple. If, for example, you want to know if we met

 catch (Exception ex) { var myExes = ex.innerExceptions<MyException>(); if (myExes.Any(x => x.Message.StartsWith("Encountered my specific error"))) { // ... } } 
+1
Mar 20 '17 at 17:16
source share



All Articles