Why try/catch around throwable? - java

In trying to refactor some I code I attempted to throw the exception in the catch clause like so -
try {
....
}
catch(Exception exception){
.....
throw exception
}
However when I attempted to throw the exception on line "throw exception" the compiler complained with a message that I needed to surround my throw clause in a new try/catch like so -
try
{
....
}
catch (Exception exception)
{
.....
try
{
throw exception
}
catch (Exception e2)
{
...
}
}
Why does the compiler require this and what use does it provide ?
Thanks

The exception java.lang.Exception is a checked exception. This means that it must either be declared in the throws clause of the enclosing method or caught and handled withing the method body.
However, what you are doing in your "fixed" version is to catch the exception, rethrow it and then immediately catch it again. That doesn't make much sense.
Without seeing the real code, it is not clear what the real solution should be, but I expect that the problem is in the original try { ... } catch handler:
If possible, you should catch a more specific exception at that point, so that when you rethrow it, it is covered by the method's existing throws list.
Alternatively, you could wrap the exception in an unchecked exception and throw that instead.
As a last resort, you could change the signature of the method to include Exception in the throws list. But that's a really bad idea, because it just pushes the problem off to the caller ... and leaves the developer / reader in the position of not knowing what exceptions to expect.

In Java, there is a distinction between checked and unchecked exceptions. An unchecked exception can essentially be thrown at any place in code and, if it's not caught somewhere, it will propagate up to the entry point of your application and then stop the process (usually with an error message and stack trace). A checked exception is different: The compiler won't let you just let it propagate, you need to either surround any code which might throw a checked exception with try-catch blocks (and "throw exception" is the simplest case if exception is an instance of a checked exception class) or you must mark the method which contains the call to code that might throw a checked exception with a "throws" declaration. If the desired behaviour is to throw an unchecked exception, then you'll need to wrap the exception in a RuntimeException. If the desired behaviour is to keep the exception checked, then you'll need to add a throws declaration to your current method.

In your original code, nothing catches the thrown exception. I would imagine you either have to specify that your function throws an exception or have another try/catch block as the compiler suggests to catch it.
Instead of
public void yourFunction(){
try {
....
}
catch(Exception exception){
.....
throw exception
}
}
try
public void yourFunction() throws Exception{
try {
....
}
catch(Exception exception){
.....
throw exception
}
}

My guess is that your trying to throw an exception sub class that isn't declared by the method as an exception type it can throw.
The following example works
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws Exception{
try {
int value = 1/0;
} catch (Exception e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
However this example will give an error.
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws RuntimeException{
try {
int value = 1/0;
} catch (Exception e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
Note in the second example I'm simply catching Exception not RuntimeException, it won't compile as I throw Exception which is an undeclared throws, even though I do declare RuntimeException.
Yes the exception is a RuntimeException but the compiler doesn't know that.
Just thought of a third working example to show you. This one also works because your throwing the same type as you declare. (note the only change is the catch block)
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws RuntimeException{
try {
int value = 1/0;
} catch (RuntimeException e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
You need to understand the differences between all three of these answers

Related

How to call a method that throws an exception in catch block?

I am trying to have an HandleException method that can handles various exceptions.
The problem is, my function returns a value. But if I use HandleException in my catch block, Java complains that the function does not return a value even though my HandleException always throw an exception.
What is a good way to fix this? Thanks!
Here is a sample code.
public class MyException {
static int foo(int num) throws Exception {
try {
return bar(num);
} catch (Exception e) {
handleException();
// throw new Exception("Exception in foo", e);
}
}
static int bar(int num) throws IllegalArgumentException {
if (num < 0) {
throw new IllegalArgumentException("Num less than 0");
}
return num;
}
static void handleException(Exception e) throws Exception {
System.err.println("Handling Exception: " + e);
throw new Exception(e);
}
public static void main(String[] args) throws Exception {
int value = foo(-1);
}
}
In my original class, I have lot of methods that have this format.
try {
...
} catch (Exception1) {
Log exception
throw appropriate exception
} catch (Exception2) {
Log exception
throw appropriate exception
}
I am trying to comeup with a cleaner way to write the catch blocks.
This is because the exception that was thrown on handleException is already caught by the catch block of the foo method. Thus the foo method no longer throws an Exception making the catch block return nothing. So if the bar method throws an exception it will go to the catch block but since the catch block is not returning anyting, Java executes the lines after the catch block but when it reaches the end it throws an error that "the method must return a result of type int" since you do not have a return statement.
You should change this part.
public class MyException {
static int foo(int num) throws Exception {
try {
return bar(num);
} catch (Exception e) {
throw handleException(e); // this will throw the exception from the handleException
// throw new Exception("Exception in foo", e);
}
}
static int bar(int num) throws IllegalArgumentException {
if (num < 0) {
throw new IllegalArgumentException("Num less than 0");
}
return num;
}
// This method now returns an exception, instead of throwing an exception
static Exception handleException(Exception e) {
System.err.println("Handling Exception: " + e);
return new Exception(e);
}
public static void main(String[] args) throws Exception {
int value = foo(-1);
}
}
In my original class, I have lot of methods that have this format... I
am trying to come up with a cleaner way to write the catch blocks.
I think the issue is more to do with understanding how the exceptions are handled in applications; its a design issue, in general.
Consider the method: int foo(int num) throws Exception
The method foo returns a value, catches an exception/handles and also throws an exception. Consider these aspects.
If the method runs normally, without errors, it returns a value. Otherwise, if there is a problem with its logic, throws an exception within the method, catches it and handles it within the catch-block of the method. The method also throws an exception.
There are two options here to consider:
Re-throw an exception, like a custom business/application exception (just log it and re-throw the same or a custom exception), which needs to be handled elsewhere - that is in a calling method up the stack.
Handle the exception: This means that the method takes care of the exception. Some business/application logic happens within the exception handling. And, the method returns a value.
The purpose of a method throwing an exception is that it is handled elsewhere, like in a calling method. The handling can be like recovering from the exception problem or displaying a message or aborting a transaction or whatever the business logic defines.
Is the exception thrown because of a business logic issue? If so it is likely that you show a message to the user or do some other logic about it and/take further steps to recover from it - as the business rules permit it.
In case the exception is thrown as a result of a situation which is not recoverable by the application's logic, do appropriate actions.
Ultimately, you have to have a clear requirement about why an exception is thrown, what you do with the exceptions thrown and how you handle them in the application. The application/logic/rules requirement influences in designing the exception handling in the code.
Notes (edit-add):
There are quite a few articles which explain about exception handling
in business application out there on the net. One can try a search
string like "Java exceptions best practices". Here is one such
article which has some useful info: Effective Java
Exceptions.
There is also the try-catch-finally construct to consider (along with various new exception features introduced with Java 7).
foo method's return type is int and return type of handleException is void, that is why compiler gives error.
(1) Here you could solve this as follows:
Throw exception as is again.
try{
return bar(num);
}
catch(Exception e){
handleException(e);
throw e;
}
(2) Moreover if you want to throw new created exception then change return type of handleException to Exception. Use
throw handleException(e);

JDK 1.7 onwards, throwing an exception object from catch block does not require a throws clause!!! Why is this so? [duplicate]

This question already has answers here:
Rethrowing an Exception: Why does the method compile without a throws clause?
(5 answers)
Closed 6 years ago.
I came across a weird scenario in java today while coding around. I have a try..catch block in my method which does not have any throws clause and I am able to throw the exception object caught in the catch block. It is an object of the Exception class, hence it is not an unchecked exception. Also, It is not printing the stacktrace if exception arises instead the exception is just getting swallowed.
Below is my code example,
public class ExceptionTest {
public void test() {
try
{
// Some code which may throw exception.
}
catch(Exception ex)
{
// Compiler should ask me to have a *throws Exception* in the signature, when I am throwing an exception object.
throw ex;
}
}
}
However, if I am throwing a new exception object instead of the caught exception object, compiler is asking me to have a throws clause in the method signature.
N.B: I am facing this situation when running in Java 7 or 8.
I am wondering, where is the thrown object going to? Anyone with any idea on this please...
You'll see this if the code in the try block can't throw any checked exception. At that point, the compiler knows that the only kind of exception caught by the catch block has to be an unchecked exception, and so it can therefore be rethrown. Note that if you assigned a different value to ex within the catch block, the compiler would no longer be able to have that assurance. At the moment, ex is effectively final.
If you try to call something that is declared to throw a checked exception within the try block, the code will fail to compile as expected.
For example:
public class ExceptionTest {
public void test() {
try {
foo();
} catch(Exception ex) {
throw ex;
}
}
public void foo() throws java.io.IOException {
}
}
Gives an error of:
ExceptionTest.java:12: error: unreported exception IOException; must be caught or declared to be thrown
throw ex;
^
As for where the exception "goes" - if the code in the try block throws an unchecked exception, it gets propagated as normal. Try this:
public class ExceptionTest {
public static void main(String[] args) {
test();
}
public static void test() {
try {
String x = null;
x.length();
} catch(Exception ex) {
throw ex;
}
}
}
Running that gives the following output, as expected:
Exception in thread "main" java.lang.NullPointerException
at ExceptionTest.test(ExceptionTest.java:10)
at ExceptionTest.main(ExceptionTest.java:4)
JLS 11.2.2 documents what exceptions a statement can throw - your code will only compile if there are no checked exceptions that can be thrown.
please check that you are really throwing an exception in the code. Otherwise the compiler will not care about catching the exception.
public class ExceptionTest {
public void test() {
try
{
throw new Exception("Error");
}
catch(Exception ex)
{
// My Compiler says that I don't catch the exception
throw ex;
}
}
}
Compiler: Error:(14, 13) java: unreported exception java.lang.Exception; must be caught or declared to be thrown

Intercept and rethrow a Java unhandled exception

I've coded a method with a catch-all handler, but I need to rethrow the exception as if it were unhandled, so that a caller (much) further up the call stack can handle it. The trivial way to do this is simply:
try {
...
} catch (Exception ex) {
// do something here...
// and rethrow
throw ex;
}
But the problem is that, because of the throw statement, Java requires this method to declare itself as throws Exception, which in turn, requires all the callers to handle the exception or declare themselves as throws Exception. And so on up the call chain...
Is there any simple way to rethrow the exception as if the current method did not handle it?
You have exactly two options with (checked) exceptions:
Handle them in the method via a try/catch (which may include rethrowing as a different exception type)
Declare that the method throws the exception.
If you want to rethrow the exception as if this method did not catch it, your only option is 2.
Note: you only want to catch (Exception e) if a method in the try block actually throws Exception. Otherwise, catch the specific exception types.
You could do what #radoh has said and just wrap into a RuntimeException, but one downside of this is your stacktrace is now polluted and will show the offending line to be where you declare throw new RuntimeException(ex).
An alternative is to use Lomboks SneakyThrows mechanism, like this:
public static void main(String[] args) {
methodWithException();
}
private static void methodWithException() {
try {
throw new Exception("Hello");
} catch (Exception e) {
Lombok.sneakyThrow(e);
}
}
Your stacktrace will remain intact, but you no longer need to declare throws Exception.
It's worth reading the documentation on why you should/shouldn't do this

Exception is never thrown in body of corresponding try statement

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.

Custom Exception class shows Unreachable catch block everytime

I've created a custom Exception class that I want to use in my application:
public class MyException extends Exception {
private static final long serialVersionUID = -2151515147355511072L;
private String message = null;
public MyException() {
super();
}
public MyException(String message) {
super(message);
this.message = message;
}
public MyException(Throwable cause) {
super(cause);
}
#Override
public String toString() {
return message;
}
#Override
public String getMessage() {
return message;
}
}
But when I try to use this class, like below, it gives a compile time error.
try {
System.out.println("this");
} catch (MyException e) {
// TODO: handle exception
}
Compile time error:
Unreachable catch block for MyException . This exception is never thrown from the try statement body
My question is if I'm extending Exception class & calling super in all constructors, then why this error is occurring?
Obviously, you are not doing anything that'd generate a MyException. First write a method with the signature throws MyException, call it and then your problem is solved. Here is an example:
public void someMethod()throws MyException
{
//some condition here.
//if met..
throw new MyException("cause");
}
and modify your main code as:
try {
someMethod();
System.out.println("this");
} catch (MyException e) {
// TODO: handle exception
}
The exception you created is a checked exception and must be thrown from somewhere to catch it.
Any exception created by a java developer by extending Exception class is a checked exception. And the rules applicable for checked exception will be applied on such exceptions.
Another form of exception is called Unchecked Exception and usually created by extending RuntimeException Class. A developer is free to catch such exception without an explicit need for throwing it somewhere from your code.
class Exception is also not thrown generally. I just want MyException behave like Exception.
This is what being further asked in one of the comments:
My take on this is you can think Exception class as a large container which have many different and unique(to the point) child exceptions defined. And mostly these fine grained exceptions are thrown from Java Code. In a abstraction hierarchy, Exception is at higher level (not Highest as, Throwable is sitting there).
Further, as a developer we all are always interested into the finer details like what kind of Exception is thrown. However, while handling exception, we sometimes write
try{
//some code lets assume throws IOException
//Some code lets assume throws FileNotFoundException
}
catch (Exception ex) {
//common handling which doesn't care if its IOException or FileNotFoundException
}
You can not intervene in this exception hierarchy by just writing MyException extends Exception. By this what you are doing is your MyException is a type of Exception not itself Exception class. So, you can't replace Exception caught in catch with your MyException.
Can you try with:
try {
System.out.println("this");
throw new MyException();
} catch (MyException e) {
// TODO: handle exception
}
Your exception wasn't thrown anywhere in the code. (try extending RuntimeException as another option)
What the compile time error says is right "This exception is never thrown from the try statement body". You don't have anything which throws MyException

Categories

Resources