Reputation: 6527
I can acheive chained Exception facility in java as
case 1:
public static void main(String[] args) {
try {
method1();
} catch (Exception e) {
System.out.println("Exception in the main method :: "+e);
}
}
private static void method1() throws Exception {
try{
System.out.println("Inside Try Block"+10/0);
} catch(ArithmeticException e){
System.out.println("Exception in method1 :: "+e);
throw e;
} finally{
System.out.println("In FinallY Block");
}
}
case 2 :
public static void main(String[] args) {
try {
method1();
} catch (Exception e) {
System.out.println("Exception in the main method :: "+e);
}
}
private static void method1() throws Exception {
try{
System.out.println("Inside Try Block"+10/0);
} catch(ArithmeticException e){
System.out.println("Exception in method1 :: "+e);
throw (ArithmeticException)new ArithmeticException().initCause(e);
} finally{
System.out.println("In FinallY Block");
}
}
And I got the output as
Exception in method1 :: java.lang.ArithmeticException: / by zero
In FinallY Block
Exception in the main method :: java.lang.ArithmeticException: / by zero
And My Question is :
Upvotes: 1
Views: 172
Reputation: 96454
You should pass the cause in as a constructor argument, instead of calling initCause.
In real code you don't see an exception thrown wrapping the same type of exception. The point is to wrap an implementation-level exception in something higher-level, so that the code catching the exception doesn't have a lot of implementation-specific special cases to handle (and implementation details don't bleed through to parts of the code that shouldn't have to care), while the chaining makes sure the original stacktrace is retained.
So you'd do something like:
private static void method1() throws HigherLevelException {
try{
System.out.println("Inside Try Block"+10/0);
} catch(ArithmeticException e){
throw new HigherLevelException(e);
}
}
Since a lot of people consider checked exceptions to be a failed experiment (not even dot-net chose to copy them), in a lot of cases the higher level exception tends to be an unchecked exception. You'll see this pattern with Spring and Hibernate.
In your first example catching an exception just to rethrow it should not be necessary. The stacktrace should be sufficient to determine where the exception was generated without having to log and rethrow. Make sure you have one centralized place that catches and logs exceptions.
Upvotes: 1
Reputation: 37859
The difference is you wrap the original ArithmeticException
exception in another exception of same type in the second case (see below why this is pointless).
Case 1 is probably what you want to use here, because you don't broaden the meaning of your exception (to a higher level).
They don't have the same purpose, let me explain...
If you set an exception as a cause, it doesn't have the same meaning. You can give a larger meaning to the ArithmeticException
by wrapping it in a higher-level exception. Here you're just wrapping it in another ArithmeticException
, which does not make sense.
A case where you might want a cause is for instance when you try to get some data from a web service: the low-level methods sending HTTP requests throw some SocketException
or HttpException
, and you wrap them in some higher-level exceptions describing what resource couldn't be loaded (for instance).
Upvotes: 1