views:

226

answers:

3

When catching an exception in .net, you can have as many type-specific exception blocks as needed. But I usually try to have at least one "general" exception catch block. But is there a way to get the type of the "real" exception thrown that is caught by the generic exception handler, perhaps using reflection?

For example, if I have

Catch ex As System.ServiceModel.FaultException(Of InvalidUser)
     ProcessModuleLoadException(Me, ex)
Catch ex As System.ServiceModel.FaultException(Of SQLExceptions)
     ProcessModuleLoadException(Me, ex)
Catch ex As System.ServiceModel.FaultException(Of DataNullReference)
     ProcessModuleLoadException(Me, ex)
Catch ex As System.ServiceModel.FaultException
     ProcessModuleLoadException(Me, ex)
Catch ex As Exception
     ProcessModuleLoadException(Me, ex)

(I have broken them out for debugging, even though I do the same thing with each exception).

In short, in "Catch ex As System.ServiceModel.FaultException" I want to examine "ex" and get the base "real" type of the exception, either as a type (mostly for debugging so I can add another catch block) or as a string (for logging).

But, inside the Catch block, "ex" has already been cast to it's parent class, so any original properties and information about the original exception seem to be lost.

Suggestions?

+3  A: 

Even though the Exception has been cast to its parent class, you can still call GetType to obtain its underlying concrete type (pardon my C#):

try {
    // Do stuff
}
catch(Exception ex) {
    Type exceptionType = ex.GetType();
}

If this is just for diagnostic purposes, you can log ex.ToString(), which includes the underlying type by default (in addition to the stack trace, etc.) like this:

System.ArgumentException: lastName
   at Tests.Program.Main(String[] args) in ...\Program.cs:line 22
Jeff Sternal
+1  A: 

.GetType will still return its actual type.

runrunraygun
A: 

What about catching it as a generic system exception then using the "is" lingo to test the actual type?

try
{
    // Something
}
catch(Exception ex)
{
    // Single catch block - catches as generic system exception
    if(ex is FaultException) {
        //Process as FaultEx
    }
    if(ex is ArithmeticException) {
        //Process as ArithEx
    }
    if(ex is ArgumentException) {
        //Process as ArgEx
    }
}
finally
{
    //Cleanup
} 
Boost2525
I've never seen this done in production code and to me it feels like a slightly unnatural thing to go out of your way to reproduce built in feature (multiple catch blocks) in a big if statement. Are there any advantages to this approach?
runrunraygun
If it still works, I can see how that would be useful if you passed "ex" to a method that then iterates over different exception types in order to log them somewhere central.
Chris Chubb
I always catch the specific exception and process accordingly, but I have built "error loggers" and "error emailers" that use this setup to take a generic ex in the method signature and reflectively log the stack / email it somewhere. The if statement comes into play when I want to log/email all types except x, y, and z.
Boost2525