I am trying to extend some legacy code to make it more tolerant of network outages. I have some (legacy) groovy code which wraps up a call to a webservice (CallWebService) via wslite. Sometimes, this call throws either a wslite.http.HTTPClientException or a java.net.ConnectException exception (this has been determined by adding
log.info("Exception " + ex.getClass().getName() + " throw");
to my log4j logging)
The code which calls this groovy code is in java and looks like the following:
public static String getDataFromWebService(String webServiceUrl, String referenceNumber) {
try {
ReturnedData returnedData = new CallWebService(webServiceUrl, referenceNumber);
return (String)returnedData.toXml();
}
catch (Exception ex) {
log.info("Exception caught: class of exception is " + ex.getClass().getName());
throw ex;
}
What I want to do, is catch the thrown exception (wslite.http.HTTPClientException or java.net.ConnectException) and retry the call (as it's probably a glitch) once or twice.
When I try and add
catch (java.net.ConnectException ex)
and build, the build fails with
exception ConnectException is never thrown in body of corresponding try statement
What should I do to be able to catch and react to the appropriate exceptions?
In your Java code, I would do something like this:
try {
callGroovy();
} catch (RuntimeException e) { // EDIT --- Should be Exception, RuntimeException
if (e instanceof HTTPClientException || e.getCause() instanceof ConnectException) {
throw e;
}
// log other exception...
}
This would be a bit safer than catching single exception types. In my experience, dynamic languages like groovy are more likely to throw unanticipated runtime exceptions. And catching all runtime exceptions would ensure that groovy exceptions do not infect the rest of your program.
Related
I have a problem with exception handling in Java, here's my code. I got compiler error when I try to run this line: throw new MojException("Bledne dane");. The error is:
exception MojException is never thrown in body of corresponding try statement
Here is the code:
public class Test {
public static void main(String[] args) throws MojException {
// TODO Auto-generated method stub
for(int i=1;i<args.length;i++){
try{
Integer.parseInt(args[i-1]);
}
catch(MojException e){
throw new MojException("Bledne dane");
}
try{
WierszTrojkataPascala a = new WierszTrojkataPascala(Integer.parseInt(args[0]));
System.out.println(args[i]+" : "+a.wspolczynnik(Integer.parseInt(args[i])));
}
catch(MojException e){
throw new MojException(args[i]+" "+e.getMessage());
}
}
}
}
And here is a code of MojException:
public class MojException extends Exception{
MojException(String s){
super(s);
}
}
Can anyone help me with this?
A catch-block in a try statement needs to catch exactly the exception that the code inside the try {}-block can throw (or a super class of that).
try {
//do something that throws ExceptionA, e.g.
throw new ExceptionA("I am Exception Alpha!");
}
catch(ExceptionA e) {
//do something to handle the exception, e.g.
System.out.println("Message: " + e.getMessage());
}
What you are trying to do is this:
try {
throw new ExceptionB("I am Exception Bravo!");
}
catch(ExceptionA e) {
System.out.println("Message: " + e.getMessage());
}
This will lead to an compiler error, because your java knows that you are trying to catch an exception that will NEVER EVER EVER occur. Thus you would get: exception ExceptionA is never thrown in body of corresponding try statement.
As pointed out in the comments, you cannot catch an exception that's not thrown by the code within your try block. Try changing your code to:
try{
Integer.parseInt(args[i-1]); // this only throws a NumberFormatException
}
catch(NumberFormatException e){
throw new MojException("Bledne dane");
}
Always check the documentation to see what exceptions are thrown by each method. You may also wish to read up on the subject of checked vs unchecked exceptions before that causes you any confusion in the future.
Any class which extends Exception class will be a user defined Checked exception class where as any class which extends RuntimeException will be Unchecked exception class.
as mentioned in User defined exception are checked or unchecked exceptions
So, not throwing the checked exception(be it user-defined or built-in exception) gives compile time error.
Checked exception are the exceptions that are checked at compile time.
Unchecked exception are the exceptions that are not checked at compiled time
Always remember that in case of checked exception you can catch only after throwing the exception(either you throw or any inbuilt method used in your code can throw) ,but in case of unchecked exception You an catch even when you have not thrown that exception.
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.
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.
I would like to catch an exception I expect but allow the others through.
The solution I have come to at the moment is:
protected void perfromCall(Class expectedException) throws Exception {
try {
response = call.call(request);
} catch (Exception e) {
if (!expectedException.isInstance(e)) {
throw new Exception(e);
}
}
}
While this will silently eat the expected exception as I would like and throw the others, what I don't like about it is that it wraps the unexpected exceptions and now I have to catch unexpected in the caller whereas previously (before trying to silently catch expected exceptions) I could let them bubble up to the test framework to fail the test.
Is there a cleaner way to say "I expected exceptions of class A, but for any other exception, let it be thrown up the chain until it's handled by the test framework above"?
Edit: I wanted to provide some justification as to why I want to do this as there were some answers (now deleted) that questioned silently eating an exception. This is for a test framework that calls a service. Some of the tests pass bad arguments to the service, so they expect an exception thrown by the service due to catching the invalid request. I therefore want to silently eat the expected exception, but still let unexpected exceptions to bubble up and fail the test.
protected void perfromCall(Class<?> expectedException) throws Exception {
try {
response = call.call(request);
} catch (Exception e) {
if (!expectedException.isInstance(e)) {
throw e;
}
}
}
What type of exception is caught by the beanshell catch(ex): Exception or Throwable?.
Example:
try {
.... } catch (ex) { }
That loosely typed catch will catch everything "Throwable." That will include Errors, Exceptions and their myriad children. You can easily confirm this with:
try {
new Throwable("Something Exceptional");
} catch (ex) {
System.err.println(ex.getMessage());
}
Throwable is a superclass (essentially) of Exception--anything that Exception catches will also be caught by Throwable. In general usage they are the same, you rarely (if ever) see other throwable types.