The exact same steps for catching multiple exceptions

I want to handle exceptions from two different types in different ways, and then do the same actions for both types of exceptions. How to do it in Java?

The following code shows what I want to do, but this is not true, since one exception cannot be caught twice.

What is the correct syntax for this?

try { // do something... } catch (ExceptionA e) { // actions for ExceptionA } catch (ExceptionB e) { // actions for ExceptionB } catch (ExceptionA | ExceptionB e) { // actions for ExceptionA & ExceptionB } 
+6
source share
5 answers

Use the catch (ExceptionA | ExceptionB e) construct catch (ExceptionA | ExceptionB e) . Inside the catch first do an instanceof check for e and handle the exception types separately. After that, do general processing for both types. This way you can do everything in one catch :

 try { // do something... } catch (ExceptionA | ExceptionB e) { if (e instanceof ExceptionA) { // handling for ExceptionA } else { // handling for ExceptionB } // common handling for both exception types } 
+4
source

If you are looking for (ExceptionA | ExceptionB) , you will be able to catch and handle the same, only one will fail. This is essentially just a new (1.7) transcript for several Exception conditions.

There is no such thing as catch(ExceptionA && ExceptionB) .

For instance:

 readFile { try { open the file; determine its size; determine its content; } catch (fileOpenFailed) { doSomething; } catch (sizeDeterminationFailed) { doSomething; } catch (contentDeterminationFailed) { doSomething; } } 

If you want to catch contentDeterminationFailed and sizeDeterminationFailed as a single Exception , then you would like to create your own Exception type that can be handled uniquely.

+1
source

Use a method for generic code.

 try { // do something... } catch (ExceptionA e) { // actions for ExceptionA doCommon(parameters); } catch (ExceptionB e) { // actions for ExceptionA doCommon(parameters); } ..... void doCommon( parameters ) { // actions for ExceptionA & ExceptionB } 

This will work for most things.
Although there are some exceptions, such as return . To do this, you can return doCommon so that the caller should return or not, and use it as:

 catch (ExceptionA e) { // actions for ExceptionA if ( doCommon(parameters) ) return; } catch (ExceptionB e) { // actions for ExceptionA if ( doCommon(parameters) ) return; } 

The native Java solution does not exist. JLS indicates (my attention):

14.20.1. Doing try-catch

A try statement without a finally block is executed by first executing a try block. Then there is a choice:

If the execution of the try block completes normally, the action is executed, and the try statement completes normally.

If the execution of the try block terminates abruptly due to a throw of the value V, then there is a choice:

If the run-time type V is an assignment compatible with (clause 5.2) that captures the exception class of any catch clause in the try statement, then the first (left-most) catch clause is selected . The value V is assigned to the parameter of the selected catch clause, and the block of this catch clause is executed, and then there is a choice:

If this block completes normally, then the try statement completes in normal mode.

If for any reason this block terminates abruptly, try the Statement terminates abruptly for the same reason.

If the run-time type of V is not an assignment compatible with the catching exception class of any catch clause in the try statement, then the try statement terminates abruptly due to a throw of V.

Thus, only the first blocking catch block is executed. It is not possible to execute two catch blocks for the same try statement.

+1
source

Will this type of solution work for you:

 try { // do something... } catch (ExceptionA | ExceptionB e) { // common code to be called for both... // .... handleException(e) } //.... void handleException(ExceptionA e) { // code for A } //.... void handleException(ExceptionB e) { // code for B } 

Thus, you first do the common steps for the two problems, after which you have the common code for each of the exceptions in the corresponding method. This way you do not need to use instance or ifs .

Another way to do this only with java constructs is to finally insert:

 boolean fail = false; try { // your code } catch (ExceptionA a) { // exceptionA specific handling fail = true; } catch (ExceptionB b) { // exceptionB specific handling fail = true; } finally { if (fail) { // common handling } } 
+1
source

You can throw an exception and process it again:

 try { try { // do something } catch( ExceptionA e) { // actions for ExceptionA throw e; } catch( ExceptionB e) { // actions for ExceptionB throw e; } } catch( ExceptionA | ExceptionB e) { // Actions for exceptions A or B } 

Perhaps for clarity, you can reorganize the methods. I assume that exceptions are marked with exceptions.

 private void doSomethingHelper() throws ExceptionA, ExceptionB { try { // do something } catch( ExceptionA e) { // actions for ExceptionA throw e; } catch( ExceptionB e) { // actions for ExceptionB throw e; } } public void doSomething() { try { doSomethingHelper(); } catch( ExceptionA | ExceptionB e ) { // Actions for exceptions A or B } } 
0
source

All Articles