I have the following scenario:
Class C{
mainCall(){
try{
//do something;
}catch(MyException e)
//doSomethingElse;
}
}
Class A{
methodOne() throws myException{
b.callMethodTwo();
}
}
class B{
callMethodTwo() throws myException{
try {
value = callService()//call some service
} catch(HttpClientErrorException | HttpServerErrorException e){
throw new MyException(e);
}
return value;
}
}
if some exceptions occured in callMethodTwo() (not HttpClientErrorException or HttpServerErrorException). What would be the flow in this case? Would the catch part in mainCall() in method C execute? I have almost 5 chain call in my code but tried to simplify here and generated this sceario.
if the statement value = callService(); in the method callMethodTwo throws
an exception of type HttpClientErrorException or HttpServerErrorException or their subtypes, it will be caught by the following catch block. This catch block will throw a new exception of type MyException which will be bubble up to methodOne which in turn bubble it up to mainCall where it will be finally caught by the catch block.
an exception of type MyException or its subtypes, it will be bubbled up from callMethodTwo to callMethodOne to mainCall where it will be finally caught by the catch block.
an exception of any other type, it will be bubbled up from callMethodTwo to callMethodOne to mainCall to the calling method of mainCall.
Exception other than handled exception wont be going into that catch block, so myException will not be thrown by callMethodTwo.
Execute and validate it. You'll never forget. callMethodTwo() will throw uncaught exception. A.methodOne() will throw the same back to. C.catch will catch it.
you have not called any method of A/B in C mainCall(). You should have some code which could throw MyException then only you can catch there.
Related
Exception is a checked exception. Why I can write catch (Exception e) when respective try block does not throw anything? This trick is not allowed with any other checked exception like IOException. Some books say that Throwable also shall be considered a checked exception, but it behaves just like Exception.
void f() {
try {
} catch (Exception e) { // fine!
}
}
void f() {
try {
} catch (Throwable e) { // also fine!
}
}
P.S. Found this in JLS:
It is a compile-time error if a catch clause can catch checked
exception class E1 and it is not the case that the try block
corresponding to the catch clause can throw a checked exception class
that is a subclass or superclass of E1, unless E1 is Exception or a
superclass of Exception.
Louis Wasserman's comment is correct. Exception is the super class of RuntimeException. Thus, catching Exception also catches all unchecked exceptions.
If you look into the code for Exception, you'll find that it extends Throwable:
public class Exception extends Throwable
Anything that can be thrown is a Throwable. Though this gives a level of flexibility since you can create a custom class that extends throwable (and throw that too). Exception is pretty much just a minimalistic wrapper around Throwable. So essentially:
try{
//something here that goes wrong causing:
throw new Exception("Thrown");
}catch(Throwable e){
System.out.println("Caught");
}
Though catching an Exception will also work. But if you create a new class that extends Throwable, catching Exception will have no effect.
Which means, if you can catch an Exception as a general statement, you can also catch its superclass, being Throwable. Note that it is not a good practice to do so, but I am mentioning it because it is possible. If you have to catch something general, catch Exception, and not Throwable.
Say I have a method doSomething() which throws a checked exception, then in my main method I enclose doSomething() in a try catch.
Question:
Say I throws Exception in doSomething(). Why can't I catch (ChildException e) in my main method?
I know I can't and that I must catch Exception, but I don't understand why.
ChildException extends Exception.
If I throws ChildException and catch Exceptionthen there's no problem understandably so. Why not the other way round?
You can catch ChildException in your main method, but because the method you call is defined as throws Exception, you will also have to catch Exception, because the compiler does not know that doSomething is only throwing ChildException. If that is what you want, then you should define doSomething as throws ChildException instead.
For example with your current setup you could do:
try {
doSomething();
} catch (ChildException e) {
// handle child exception
} catch (Exception e) {
// handle other exceptions
}
As commented by MC Emperor, order of catch blocks is important, if you'd reverse the order and catch Exception first, then that block will also handle ChildException, and the ChildException-specific block will not be used.
Alternatively, change doSomething():
public void doSomething throws ChildException {
// ...
}
If your code throws ChildException child, you can catch it with Exception parent , because ChildException extends Exception, so child is assignable to parent i.e. you can write something like
Exception parent = child;
But if your code says you are throwing an Exception, the compiler takes you at face value and assumes that the exception type thrown by your method can be of any subclass of Exception or of the class Exception itself.
For example , your method may throw another ChildException2. So, in that case it is not assignable to ChildException in the catch clause of main method. The ChildException2 is neither handled nor declared.
So, the compiler doesn't allow you to continue with just catching the ChildException and asks you to either catch the type Exception or declare it.
I'm extending the class RecordingCommand from org.eclipse.emf.transaction.RecordingCommand; I need to override protected method doExecute(), the method definition does not contain any exception to throw but there is option that inside my code I have and exception and I want to catch it and raise it up, how should I handle this kind of exception, here I throw the message e but I'm not sure that this is the right way to do that.
I hope you will understand the issue since I think it more sophisticated that just throw E
i.e.throw the exception
#Override
protected void doExecute() {
try {
//my logic
} catch(Exception e) {
throw e;
}
}
You can always throw an UncheckedException from a method, which need not be declared in the throws clause.
So, you wrap your exception in any unchecked exception like that extends RuntimeException or even RuntimeException itself.
try {
//my logic
} catch(Exception e) {
throw new RuntimeException(e);
}
And just for the sake of completeness, it is a bad idea to have a single catch block for Exception, which will catch all the exceptions. Rather you should have catch block for specific type of exception your method may throw.
I have basic doubt in Java Exceptions
i.e., All checked exceptions extends from Exception class and Unchecked Exceptions extend from RuntimeException. But Runtime Exception also extends from Exception.
But why to propagate try... catch block with checked Exceptions but not in Unchecked Exceptions?
In general, you should add different catch blocks for each specific type of exception you intend to handle. If you're trying to handle (by rethrowing) checked exceptions, then you should know which type of exceptions to rethrow -- just add a catch block to rethrow each of those exception types.
I think you are asking, "How can I catch Exception but not RuntimeException ?
You probably should not be trying to do that. You should catch specific types of exceptions when possible. If you need to handle all errors, then you should catch Exception and that catches everything.*
You would rarely want to do catch (NullPointerException) because if you ever know that you can have a null then you should check for it. If your code is causing NullPointerException or ArrayOutOfBoundsException then you should fix the code so that it no longer throws those.
This code should show you how to do what you asked about:
public static void throwSomething(Exception throwMe)
{
try {
throw throwMe;
}
catch(Exception ex) {
// Check if the object is a RuntimeException
if(ex instanceof RuntimeException) {
// Throw the same object again.
// Cast to RuntimeException so the compiler will not
// require "throws Exception" on this method.
throw (RuntimeException) ex;
}
System.out.println("Caught an instance of a " +
ex.getClass().toString());
}
}
*Actually, catch(Throwable) will catch everything including Errors.
The easiest way is this:
try {
//do stuff
} catch(RuntimeException e) {
throw e;
} catch(SpecificCheckedException e) {
//handle
} catch(Exception e) {
//handle
}
i have question regarding chain exception
try{ } catch(Exception e) { throw new SomeException(); }
if i do like this
my eclipse will prompt error at line throw new SomeException();
stating "unhandled exception"
and i must put something like
try{ } catch(Exception e) {
try{ throw new SomeException(); } catch(Exception e){}
}
why must do like this
because tutorial that i read .example http://java.sys-con.com/node/36579 , does not have to do this
You'll need to declare that the method throws another exception, if the exception is a checked exception.
("The unchecked exceptions classes are the class RuntimeException and its subclasses, and the class Error and its subclasses. All other exception classes are checked exception classes." -- Java Language Specification, Second Edition, Section 11.2)
For example, rather than:
void someMethod {
try {
// Do something that raises an Exception.
} catch (Exception e) {
throw new SomeException(); // Compile error.
}
}
A throws needs to be added to the method declaration:
void someMethod throws SomeException {
try {
// Do something that raises an Exception.
} catch (Exception e) {
throw new SomeException(); // No problem.
}
}
It depends if SomeException is a checked exception or not. If it is (it extends Exception but not RuntimeException) then you have to declare it on the method or throw a RuntimeException instead.
This is what your code should look like:
...) throws SomeException {
....
try {
....
} catch (Exception e) {
throw new SomeException(e);
}
If some exception doesn't have a constructor which takes an exception, then do this:
throw (SomeException) new SomeException().initCause(e);
That way when the exception is ultimately caught, you know the root cause of the problem.
your method must declare that it may throw that exception. so, you must add:
throws SomeException {
at the end of your method's header.
You need to add "throws SomeException" to your method declaration. You need to specify any exception types that your method throws except for exceptions that descend from RuntimeException.