Determining Exception Type After the Exception Is Caught

Determining exception type after the exception is caught?

You can actully determine type inside a catch(...), but it is not very useful:

#include <iostream>
#include <exception>

class E1 : public std::exception {};
class E2 : public std::exception {};

int main() {
try {
throw E2();
}
catch( ... ) {
try {
throw;
}
catch( const E1 & e ) {
std::cout << "E1\n";
}
catch( const E2 & e ) {
std::cout << "E2\n";
}
}
}

How to check which exception type was thrown in Java?

If you can, always use separate catch blocks for individual exception types, there's no excuse to do otherwise:

} catch (NotAnInt e) {
// handling for NotAnInt
} catch (ParseError e) {
// handling for ParseError
}

...unless you need to share some steps in common and want to avoid additional methods for reasons of conciseness:

} catch (NotAnInt | ParseError e) {
// a step or two in common to both cases
if (e instanceof NotAnInt) {
// handling for NotAnInt
} else {
// handling for ParseError
}
// potentially another step or two in common to both cases
}

however the steps in common could also be extracted to methods to avoid that if-else block:

} catch (NotAnInt e) {
inCommon1(e);
// handling for NotAnInt
inCommon2(e);
} catch (ParseError e) {
inCommon1(e);
// handling for ParseError
inCommon2(e);
}

private void inCommon1(e) {
// several steps
// common to
// both cases
}
private void inCommon2(e) {
// several steps
// common to
// both cases
}

Identifying Exception Type in a handler Catch Block

UPDATED: assuming C# 6, the chances are that your case can be expressed as an exception filter. This is the ideal approach from a performance perspective assuming your requirement can be expressed in terms of it, e.g.:

try
{
}
catch ( Web2PDFException ex ) when ( ex.Code == 52 )
{
}

Assuming C# < 6, the most efficient is to catch a specific Exception type and do handling based on that. Any catch-all handling can be done separately

try
{
}
catch ( Web2PDFException ex )
{
}

or

try
{
}
catch ( Web2PDFException ex )
{
}
catch ( Exception ex )
{
}

or (if you need to write a general handler - which is generally a bad idea, but if you're sure it's best for you, you're sure):

 if( err is Web2PDFException)
{
}

or (in certain cases if you need to do some more complex type hierarchy stuff that cant be expressed with is)

 if( err.GetType().IsAssignableFrom(typeof(Web2PDFException)))
{
}

or switch to VB.NET or F# and use is or Type.IsAssignableFrom in Exception Filters

How do I determine what type of exception occurred?

The other answers all point out that you should not catch generic exceptions, but no one seems to want to tell you why, which is essential to understanding when you can break the "rule". Here is an explanation. Basically, it's so that you don't hide:

  • the fact that an error occurred
  • the specifics of the error that occurred (error hiding antipattern)

So as long as you take care to do none of those things, it's OK to catch the generic exception. For instance, you could provide information about the exception to the user another way, like:

  • Present exceptions as dialogs in a GUI
  • Transfer exceptions from a worker thread or process to the controlling thread or process in a multithreading or multiprocessing application

So how to catch the generic exception? There are several ways. If you just want the exception object, do it like this:

try:
someFunction()
except Exception as ex:
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(ex).__name__, ex.args)
print message

Make sure message is brought to the attention of the user in a hard-to-miss way! Printing it, as shown above, may not be enough if the message is buried in lots of other messages. Failing to get the users attention is tantamount to swallowing all exceptions, and if there's one impression you should have come away with after reading the answers on this page, it's that this is not a good thing. Ending the except block with a raise statement will remedy the problem by transparently reraising the exception that was caught.

The difference between the above and using just except: without any argument is twofold:

  • A bare except: doesn't give you the exception object to inspect
  • The exceptions SystemExit, KeyboardInterrupt and GeneratorExit aren't caught by the above code, which is generally what you want. See the exception hierarchy.

If you also want the same stacktrace you get if you do not catch the exception, you can get that like this (still inside the except clause):

import traceback
print traceback.format_exc()

If you use the logging module, you can print the exception to the log (along with a message) like this:

import logging
log = logging.getLogger()
log.exception("Message for you, sir!")

If you want to dig deeper and examine the stack, look at variables etc., use the post_mortem function of the pdb module inside the except block:

import pdb
pdb.post_mortem()

I've found this last method to be invaluable when hunting down bugs.

How to determine if an exception is of a particular type

before your current catch add the following:

catch(DbUpdateException ex)
{
if(ex.InnerException is UpdateException)
{
// do what you want with ex.InnerException...
}
}

From C# 6, you can do the following:

catch(DbUpdateException ex) when (ex.InnerException is UpdateException)
{
// do what you want with ex.InnerException...
}

Check for exception type inside Exception catch block and log it

The is operator is performing a boolean operation on whether or not your exception can be converted to the target type, but that type conversion is not then passed to the first branch of your ternary.

You can either recast:

var bodyString = ex is JsonParsingException 
? ((JsonParsingException)ex).GetUnderlyingByteArrayUnsafe()
: null;

Or you can use the as operator which will attempt to make the conversion for you and if it cannot, will return null:

var jsonParsingException = ex as JsonParsingException;
var bodyString = jsonParsingException != null
? jsonParsingException.GetUnderlyingByteArrayUnsafe()
: null;

Note that with C#7 pattern matching, you can also output the result to a temporary local variable and enable a one-liner:

var bodyString = ex is JsonParsingException j
? j.GetUnderlyingByteArrayUnsafe()
: null;

and finally, @mjwills pointed out that you can wrap the as operation in braces and check for null with the null propagation operator, allowing for a one-liner as well:

var bodyString = (ex as JsonParsingException)?.GetUnderlyingByteArrayUnsafe();

Exception Handling for specifc exception type

Ideally you should handling each Exception individually like so:

try
{

}
catch (IOException ex)
{
// Log specific IO Exception
}
catch (NullReferenceException ex)
{
// Log Specific Null Reference Exception
}
catch (Exception ex)
{
// Catch everything else
}

You could do:

    string exceptionErrorMessage;

try
{

}
catch (IOException ex)
{
// Log specific IO Exception
exceptionErrorMessage = ex.Message;
}
catch (NullReferenceException ex)
{
// Log Specific NullReferenceException
exceptionErrorMessage = ex.Message;
}
catch (Exception ex)
{
// Catch everything else
exceptionErrorMessage = ex.Message;
}

if (!string.IsNullOrEmpty(exceptionErrorMessage))
{
// use your logger to log exception.
Console.WriteLine(exceptionErrorMessage);
}

Here's the correct to OPs code using the same method he wanted:

try
{

}
catch (Exception e)
{
var exType = e.GetType().Name;
switch (exType)
{
case "IOException":
case "NullReferenceException":
Console.WriteLine(e.Message);
break;
}
}


Related Topics



Leave a reply



Submit