Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple specific catch or one catches all?

I've seen this topic arise sometimes in the past but even after Googling about it, I still can't figure out what would be a good and elegant way to deal with it, so here it goes.

Say I have some code that throws various exceptions...

try {
  /* some code that throws these exceptions */
} catch (NoSuchAuthorityCodeException e) {
    throw new MyAPIException("Something went wrong", e);
} catch (FactoryException e) {
    throw new MyAPIException("Something went wrong", e);
} catch (MismatchedDimensionException e) {
    throw new MyAPIException("Something went wrong", e);
} catch (TransformException e) {
    throw new MyAPIException("Something went wrong", e);
}

... and as we can see, I just wrap these exceptions and throw a new one saying that something went wrong within my API.

This seems to me a overly repetitive code, so one would simply catch an Exception type and handle wrap it and throw a new one.

try {
  /* some code that throws these exceptions */
} catch (Exception e) {
    throw new MyAPIException("Something went wrong", e);
}

In this case it stays way more simpler, but the thing is we'd be catch also every RuntimeException. Given this, we could catch-re-throw the RuntimeException so we could avoid this.

try {
  /* some code that throws some exceptions */
} catch (RuntimeException e) {
    throw e;
} catch (Exception e) {
    throw new MyAPIException("Something went wrong", e);
}

Its a bit bulky but it does the trick. Now theres another little issue about the catch(Exception e), that if my inner API throws another MyAPIException it would also be caught, wrapped and throwed within another MyAPIException. In this particular case we could also catch MyAPIException and re-throw it.

try {
  /* some code that throws some exceptions */
} catch (RuntimeException e) {
    throw e;
} catch (MyAPIException e) {
    throw e;
} catch (Exception e) {
    throw new MyAPIException("Something went wrong", e);
}

Well, its getting messy again, but in this case we prevent wrapping MyAPIException and simply re-throw it. But, theres also another issue with the catch (Exception e) block that is if the inner API changes and start throwing another kind of exception (some other than these 4 mentioned above), the compiler wouldn't say anything about it and we wouldn't have a clue. Not that this would be a major problem, since probably I would treat it in the same manner.

With this scenario, I think the question is, which one is better and are there better options?

like image 616
Pablo Cabrera Avatar asked Aug 31 '10 11:08

Pablo Cabrera


People also ask

Is there a way to catch multiple exceptions at once and without code duplication?

In C#, You can use more than one catch block with the try block. Generally, multiple catch block is used to handle different types of exceptions means each catch block is used to handle different type of exception.

Can we use multiple catches when can we use multiple catches?

Java Multi-catch block A try block can be followed by one or more catch blocks. Each catch block must contain a different exception handler. So, if you have to perform different tasks at the occurrence of different exceptions, use java multi-catch block.

Can you use multiple catch and single?

You cannot have multiple try blocks with a single catch block. Each try block must be followed by catch or finally. Still if you try to have single catch block for multiple try blocks a compile time error is generated.

Can we handle multiple exceptions by using single catch block?

In Java SE 7 and later, a single catch block can handle more than one type of exception. This feature can reduce code duplication and lessen the temptation to catch an overly broad exception.


1 Answers

Since you are stuck with Java5 and you use a proprietary exception, why not put all that exception logic into the exception class.

Useage

try
{
     // some code that might throw one of several exceptions
}
catch ( Exception cause )
{
     MyAPIException . handle ( cause ) ;
}

MyAPIException contains the logic

class MyAPIException extends Exception
{
    private MyAPIException ( String message , Throwable cause ) { super ( message , cause ) ; }

    private static void myAPIException ( Exception cause ) throws MyAPIException
    {
         throw new MyAPIException ( "Something Went Wrong" , cause ) ;
    }

    public static void handle ( Exception e ) throws MyAPIException
    {
          try
          {
               throw ( e ) ;
          }
          catch ( RuntimeException cause )
          {
                throw cause ;
          }
          catch ( MyAPIException cause )
          {
                 throw cause ;
          }
          catch ( NoSuchAuthorityCodeException cause )  // repeat for other exceptions
          {
                 myAPIException ( cause ) ;
          }
          catch ( Exception cause ) // this should not happen
          {
                  assert false ; // or log it or throw a RuntimeException ... somehow signal that programming logic has failed
          }
    }
}
like image 185
emory Avatar answered Sep 18 '22 17:09

emory