I'm working on cleaning up some of my code and I came to a point where I wasn't sure which route would be better.
Currently I have a single try catch block over the majority of my method and it handles a few separate exceptions at the end, but I figured having more try catch blocks would be better just for maintenance. However, while breaking down the code I came to a point where I was writing multiple blocks for the same type of exception. I can see the up side to writing a block for each part since I can then give more specifics to why it failed.
My question is this... is there a downside to doing this? Could there be performance issues or some other hidden monster that I'm not seeing?
Also, what is the preferred way of handling multiple exceptions in a method, is there an industry standard?
Just to better illustrate my point here's some pseudo code
//multiple try catch for same exception try { //some code here } catch (MyException e) { //specific error message here } try { //some different code here } catch (MyException e) { //more specific error message indicating a different issue }
Yes, we can define one try block with multiple catch blocks in Java. Every try should and must be associated with at least one catch block.
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.
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.
Nesting try-catch blocks severely impacts the readability of source code because it makes it to difficult to understand which block will catch which exception.
I always try to reduce levels of nesting for readability and maintainability. If you have n try/catch blocks, each handling the same type of exception, why not refactor the code that can throw the exception into methods...it would look something like:
try { firstBatchOfTricky(); secondBatchOfTricky(); .... nthBatchOfTricky(); } catch (ItWentBoomException e) { // recover from boom } catch (ItWentBangException e) { // recover from bang }
This is much more readable than having multiple try/catches. Note that your methods should describe what they do in the spirit of self documenting code.
Since you have your own Exception type, you can add the data you need to the exception to do different things in the catch block. When you say 'more specific message', you can just throw the exception with the detailed message; you shouldn't need multiple catch blocks. If you want to do drastically different things based on the state of the exception, just create more exception types and catch blocks but only one try block, as my pseudocode shows...
Finally, if you can't recover from the exception(s), you should not clutter the code with catch blocks. Throw a runtime exception and let it bubble. (Good advice from @tony in the comments)
This isn't a performance or personal preferences question: It's a functionality and requirements question.
Suppose I write:
Scenario 1:
try { doThingA(); } catch (SomeException panic) { System.out.println("doThingA failed"); } try { doThingB(); } catch (SomeException panic) { System.out.println("doThingB failed"); }
Scenario 2:
try { doThingA(); doThingB(); } catch (SomeException panic) { System.out.println("doThingA or doThingB failed"); }
These two scenarios are not equivalent: They do different things. In Scenario 1, if doThingA throws the exception, doThingB still executes. In Scenario 2, if doThingA throws the exception, doThingB is not executed. So the question is not which gives better performance or which is more readable code, but rather, if doThingA fails, should doThingB still be executed or not?
If what you really want is the second behavior, but you want different messages to tell the user what went wrong, then you should either throw different exceptions, or put the text of the message into the exception, i.e.
void doThingA() throws SomeException { ... whatever code ... if (theWorldIsAboutToEnd) throw new SomeException("doThingA failed"); }
Then in the catch clause, instead of displaying a constant string, displayt SomeException.toString or SomeException.getMessage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With