I should know this, but for some reason I can't figure it out right now.
Is there a way to rewrite this code to avoid instanceof?
try {
//Exceptions may happen
} catch (Exception1 exception1) {
//do stuff only in case of Exception1
} catch(Exception e) {
// do stuff in all exception cases except Exception1
if (e instanceof Exception2) {
// do stuff only in case of Exception2
}
}
If you're going to have your exception handling for Exception inline, and don't want to repeat it, then the only solution is the OP solution.
However, if you can put the common exception handling into a function, then this would be neat:
try {
//Exceptions may happen
} catch (Exception1 exception1) {
//do stuff only in case of Exception1
} catch(Exception2 e) {
doCommonStuff();
doException2Stuff();
} catch(Exception e) {
doCommonStuff();
}
However, the above may lead to a small problem in terms of whether you want to pass control to outside of the try/catch block, or whether you're hoping to return a value, or even throw another exception.
You may find that although all paths of your code DO throw an exception, that the above construct, of using common exception handler methods, may look to the compiler like some control paths don't.
You can, therefore, express a common exception handler, that always throws an exception like this:
private <T> T throwLastException(Exception2 input) {
// blah blah blah
throw new SomeException();
}
and this can be called as part of a return statement that appears to guarantee the calling function returns a value, when in fact it's just telling the compiler not to worry :)
Without any further context IMO the following is good enough:
try {
//Exceptions may happen
} catch (Exception1 exception1) {
//do stuff only in case of Exception1
} catch (Exception2 exception2) {
some_method();
}
catch(Exception e) {
some_method();
}
Where some_method would encapsulate the code related with "// do stuff in all exception cases except Exception1"
Consider encapsulating common code between catch clauses 2 & 3 on some method, for instance:
try {
//code
} catch (Exception1 e1) {
// specific code for exception 1
} catch (Exception2 e2) {
// specific code for exception 2
method();
} catch (Exception e) {
method();
}
Catch two types of exception in one block with the "|" operator.. And maybe you can execute code that you have to execute in any case in the finally statement. That are all options you have, and i think creating a method and calling it isn't a option, when you're trying to make your code more readable, what I think you're trying to do
try {
//code
} catch (Exception1 | Exception2 e2) {
// specific code for exception 1 & 2
} catch (Exception e) {
// handle other exceptions
} finally {
// execute in any case
}
Related
For a project I've been working on, we have some blocks that look like this:
Class A:
try {
callSomeMethod();
}
catch (Exception e) {
throw new SomeCustomExceptionTypeForMetrics("");
}
However, I was tasked with replacing all instances where we catch generic exceptions with only specific "expected" types of exceptions.
The problem is callSomeMethod() has something like this
Class B:
try {
if (someCondition...) {
}
else {
//failed
throw new RuntimeException("Timeout while waiting for results")
}
}
catch(InterruptedException e) {
// do some failure stuff here
throw new RuntimeException("Something here");
}
Ideally, my group has asked me to change as little as possible, and I can't change the signature for callSomeMethod(), but they also don't want to just catch any RuntimeException in Class A since they don't want to catch just any type of RuntimeException - only the ones we're excepting from Class B.
What is the best way to handle this?
Supposing that your callSomeMethod's signature contains throws Exception, and you can't change it: Change the RuntimeExceptions in the method to a custom Exception class, and then in Class A:
try {
callSomeMethod();
}
catch (Exception e) {
if(e instanceof CustomException)
//Log it or something, for metrics?
}
This is kind of silly, but might be necessary if you can't change the method signature. (If you can change it, you could catch the CustomException directly.) You could even make a method in your logger that takes an Exception, checks what type it is, and acts accordingly. Then just use this method in every catch statement that you need to edit.
While designing this solution, keep in mind that RuntimeExceptions don't need to be caught. It could save you some trouble.
If you chnage your code in class B as below
try {
if (someCondition...) {
}
else {
//failed
throw new MyRuntimeException("Timeout while waiting for results")
}
}
catch(InterruptedException e) {
// do some failure stuff here
throw new MyRuntimeException("Something here");
}
and define MyRuntimeException as :
class MyRuntimeException extends RuntimeException{
..
}
In class A, you only need to catch MyRuntimeException exception .
Hope this solve your problem!!
I am a little doubtful this is possible, but getting more information about this would be very helpful. I am wondering how to catch all exceptions that a function doesn't already throw.
Say I have a function:
public int func(int a, int b) throws IOException, EOFException {
try {
doSomething(a, b);
} catch (AllExceptionsExceptionIOandEOF e) {
doSomethingWithError(e);
}
return 0;
}
Is there a way to tell Java how to do that? I know throwing the generic Exception works for all, but I want to throw all but the thrown exception.
If this is considered bad practice, why? And what is a good alternative to accomplish the same goal?
(PS -- I know, I know the adage that all possible exceptions need to be handled individually. For my purposes, I just want to catch the errors, log them in a database, and see what things are coming up that we missed during development. I am reluctant to catch the generic Exception when my function is already throwing 2 exceptions)
It just occured to me, one way would be to say:
try {
doSomething(a, b);
} catch (AllExceptionsExceptionIOandEOF e) {
doSomethingWithError(e);
if (e instanceof IOException)
throw e;
if (e instanceof EOFException)
throw e;
}
Is there a more elegant way of doing this though?
EDIT - The project is done in Java 6 compliance, unfortunately. I know Java 7 has made Try/Catches a bit more flexible though.
try {
doSomething(a, b);
} catch (IOException e) {
throw e;
} catch (EOFException e) {
throw e;
} catch (Exception e){
doSomethingWithError(e);
}
In pre java1.7
try{}
catch(FileNotFoundException e){}
catch(IOException e){}
catch(Exception e){
//anything not handled in other catch clause
}
Just be sure to declare your catch clauses from more specific to less specific.
In java 1.7 you can do fancier things:
catch(IOException | EOFException e){}
Since EOFException extends IOException you can catch IOException and throw it as below
catch( IOException e){
//do what you want
}
From java 1.7 you can group exceptions behaviour.
try{
//some code
}catch( IOException | AnotherException e){
//do what you want
}catch(RuntimeException re){
//happen a runtimexception
}
And to catch all exceptions that function doesn't throw it only can be RuntimeException and subclasses cause they are unchecked exceptions.
And for hierachy exceptions, first the subclasses and then more general.
For example :
catch(EOFException e){
}catch(IOException e){
}
By the way, only catch exception once.
Per the other answers, especially pre-Java 1.7, you don't have a really good answer. If this is going to be done in many places in your code, and you primarily want it for development, I might suggest creating a special handler:
class ExceptionHandler
{
public static void handle(Throwable t, Class<? extends Exception> rethrowClasses...)
{
for (Class e : rethrowClasses)
{
if e.isInstance(t)
{
throw t;
}
}
}
}
Then in your exception block:
try
{ ... }
catch (Exception e)
{
ExceptionHandler.handle(e, IOException.class, EOFException.class);
// other processing
}
That would re-throw the requested exceptions, and you have a vararg list of which exceptions to re-throw for each exception block. You can re-use that and only add one line to each exception block. You could adjust the logic as needed to log the non-handled exceptions, or whatever else is needed.
It's not great, but there just aren't a lot of good solutions to your problem.
I have an interesting scenario where I am setting an HttpServletResponse error in a catch clause. The "response.sendError(..)" also throws an exception. What is the best way to deal with exceptions during exception handling to preserve the original exception detail?
I have something like this:
try {
...
} catch(Exception e) {
try {
response.sendError(500);
} catch(IOException e2) {
//Can I do something like:
//'throw new ServletException(e,e2)' here?
}
}
In other words, what is the best way to bundle up the information from both exceptions into the next exception thrown? I don't want to lose the information from the first exception when handling the second.
In general, multiple try catch blocks seem horrible for readability. Would ideally like to avoid that mess. Could always bundle up the embedded try/catch in a method... still seems bad though and doesn't resolve keeping all the exception detail.
Try:
try {
...
} catch(Exception e) {
try {
response.sendError(500);
} catch(IOException e2) {
e2.initCause(e);
throw e2;
}
}
Using initCause() will not aways work if the exception already has a cause. Instead you can use addSupressed() to include the an exception in a different exceptions's stack trace.
try {
...
} catch(Exception e) {
try {
response.sendError(500);
} catch(IOException e2) {
e.addSuppressed(e2);
throw e;
}
}
I have the following code:
try {
/* etc. 1 */
} catch (SomeException e) {
/* etc. 2 */
} catch (SomeException e) {
/* etc. 3 */
} finally {
/*
* do something which depends on whether any exception was caught,
* but should only happen if any exception was caught.
*/
/*
* do something which depends on whether an exception was caught and
* which one it was, but it's essentially the same code for when no
* exception was caught.
*/
}
So, I want to keep my caught exception. Any way to do this other than assigning to a variable in every catch block?
Edit: Just to clarify, please don't post answers suggesting I use a variable scoped outside the try block. I know I can do that, the whole point of this question is finding an alternative.
Now, what I would really like to have is more flexible catch block, so that multiple catch blocks could catch the same exception, e.g. catch(Exception e) would catch everything even if it was already caught, catch(Exception e) except(NullPointerException, IllegalArgumentException) would skip the excepts. And a catch block could do catchingcontinue; to skip all other catch blocks for the same try block and catchingbreak; to skip even the finally.
Try this:
try {
// your code throwing exceptions
} catch (Exception e) { // This catch any generic Exception
// do whatever you want to do with generic exception
...
if (e instanceof SomeException) {
...
} else if (e instanceof OtherException) {
...
}
}
using java 7 you can even do this:
try {
// your code throwing exceptions
} catch (SomeException|OtherException e) { // This catch both SomeException and OtherException
// do whatever you want to do with generic exception
...
if (e instanceof SomeException) {
...
} else if (e instanceof OtherException) {
...
}
}
Keep a variable outside the scope of the catch block and assign it in the catch block.
Buy I strongly recommend that you do not do this.
Finally block should be used for resource cleanup or any similar functionality that need to be run regardless of the exceptions.
All the exception handling should be done in the catch blocks, not the finally blocks.
You will need to assign it to a variable outside the try-catch block and use it on the finally block.
Exception caughtException = null;
try {
/* etc. 1 */
} catch (SomeException e) {
caughtException= e;
} catch (SomeOtherException e) {
caughtException= e;
} finally {
if (caughtException != null) {
/*
* do something which depends on whether any exception was caught,
* but should only happen if any exception was caught.
*/
}
}
Looks like you want to do some auditing. Why don't you use some annotations and AOP to handle the behavior, of course with a good exception handling to catch those exceptions on the before or after.
What I would recommend here is that you extract the details of the exception handling out to new methods, and call those methods from catch blocks that are as specific as necessary to avoid instanceof checks. This has the advantage of not using instanceof, keeping exception handling code in catch blocks instead of in finally, and clearly separating shared exception handling code from specific exception handling code. Yes, there's some shared code between the three catch blocks, but it's a single clear line of code, which seems acceptable to me.
try {
// do work that uses resources and can generate any of several exceptions
} catch (SomeException1 e) {
standardExceptionHandler(e);
specificExceptionHandler1(e);
} catch (SomeException2 e) {
standardExceptionHandler(e);
specificExceptionHandler2(e);
} catch (Exception e) {
standardExceptionHandler(e);
} finally {
// this would include only code that is needed to cleanup resources, which is
// what finally is supposed to do.
}
This question already has answers here:
Can I catch multiple Java exceptions in the same catch clause?
(10 answers)
Closed 8 years ago.
I need to catch two exceptions because they require the same handling logic. I would like to do something like:
catch (Exception e, ExtendsRuntimeException re) {
// common logic to handle both exceptions
}
Is it possible to avoid duplicating the handler code in each catch block?
Java 7 and later
Multiple-exception catches are supported, starting in Java 7.
The syntax is:
try {
// stuff
} catch (Exception1 | Exception2 ex) {
// Handle both exceptions
}
The static type of ex is the most specialized common supertype of the exceptions listed. There is a nice feature where if you rethrow ex in the catch, the compiler knows that only one of the listed exceptions can be thrown.
Java 6 and earlier
Prior to Java 7, there are ways to handle this problem, but they tend to be inelegant, and to have limitations.
Approach #1
try {
// stuff
} catch (Exception1 ex) {
handleException(ex);
} catch (Exception2 ex) {
handleException(ex);
}
public void handleException(SuperException ex) {
// handle exception here
}
This gets messy if the exception handler needs to access local variables declared before the try. And if the handler method needs to rethrow the exception (and it is checked) then you run into serious problems with the signature. Specifically, handleException has to be declared as throwing SuperException ... which potentially means you have to change the signature of the enclosing method, and so on.
Approach #2
try {
// stuff
} catch (SuperException ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
// handle exception
} else {
throw ex;
}
}
Once again, we have a potential problem with signatures.
Approach #3
try {
// stuff
} catch (SuperException ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
// handle exception
}
}
If you leave out the else part (e.g. because there are no other subtypes of SuperException at the moment) the code becomes more fragile. If the exception hierarchy is reorganized, this handler without an else may end up silently eating exceptions!
Java <= 6.x just allows you to catch one exception for each catch block:
try {
} catch (ExceptionType name) {
} catch (ExceptionType name) {
}
Documentation:
Each catch block is an exception handler and handles the type of
exception indicated by its argument. The argument type, ExceptionType,
declares the type of exception that the handler can handle and must be
the name of a class that inherits from the Throwable class.
For Java 7 you can have multiple Exception caught on one catch block:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
Documentation:
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.
Reference:
http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
If you aren't on java 7, you can extract your exception handling to a method - that way you can at least minimize duplication
try {
// try something
}
catch(ExtendsRuntimeException e) { handleError(e); }
catch(Exception e) { handleError(e); }
For Java < 7 you can use if-else along with Exception:
try {
// common logic to handle both exceptions
} catch (Exception ex) {
if (ex instanceof Exception1 || ex instanceof Exception2) {
}
else {
throw ex;
// or if you don't want to have to declare Exception use
// throw new RuntimeException(ex);
}
}
Edited and replaced Throwable with Exception.
http://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html covers catching multiple exceptions in the same block.
try {
// your code
} catch (Exception1 | Exception2 ex) {
// Handle 2 exceptions in Java 7
}
I'm making study cards, and this thread was helpful, just wanted to put in my two cents.
Before the launch of Java SE 7 we were habitual of writing code with multiple catch statements associated with a try block.
A very basic Example:
try {
// some instructions
} catch(ATypeException e) {
} catch(BTypeException e) {
} catch(CTypeException e) {
}
But now with the latest update on Java, instead of writing multiple catch statements we can handle multiple exceptions within a single catch clause. Here is an example showing how this feature can be achieved.
try {
// some instructions
} catch(ATypeException|BTypeException|CTypeException ex) {
throw e;
}
So multiple Exceptions in a single catch clause not only simplifies the code but also reduce the redundancy of code.
I found this article which explains this feature very well along with its implementation.
Improved and Better Exception Handling from Java 7
This may help you too.