Why am I getting errors with my Java try...catch? - java

I'm starting to teach myself more about Java error handling, and this is my first program where I'm trying to see specific errors instead of using catch (Exception e) as a generic catch-all catch.
I'm deleting a file and returning a message that the file was deleted successfully or that the deletion was a failure. In cases where the deletion fails, I want to deliver an error message if the file is not found.
Here's where I am so far:
public static void deleteOldConcatFiles(File concatFile) {
try
{
if(concatFile.delete()) {
System.out.println(concatFile.getName() + " is deleted!");
} else {
System.out.println("Delete operation failed.");
}
}
//
catch(FileNotFoundException f) {
System.out.println("Exception: "+ f.getMessage().getClass().getName());
}
}
When I run that, I'm getting a warning: This this is an unreachable catch block for FileNotFoundException. This exception is never thrown from the try statement body.
However, when I run with THIS catch block,
catch(Exception f) {
System.out.println("Exception: "+e.getMessage().getClass().getName());
}
I get no error or warning message.
Why is this happening, and what can I do to fix it?

File.delete() does not throw FileNotFoundException, even if the file does not exist.
FileNotFoundException is a checked exception (i.e., not a RuntimeException), so any code that throws it must declare it. Because File.delete() does not declare that it throws FileNotFoundException, the compiler guarantees that it won't, and can promise that your catch block will never be invoked.
The second, catch-all block does not generate a warning because it also catches RuntimeExceptions (RuntimeException extends Exception), which the compiler does not check for you. Thus, it might be invoked, the compiler isn't sure, so it doesn't warn you.

Java supports two kinds of exceptions: checked exceptions (statically checked) and unchecked exceptions (RuntimeException and its subtypes).
The Java compiler can tell at compile time whether a checked exception (such as FileNotFoundException) can be thrown or can definitely not be thrown. It can't tell that for unchecked exceptions (such as IndexOutOfBoundsException). So it will warn about attempts to catch checked exceptions that cannot arise.
If you catch Exception, it will never complain, because RuntimeException is a subtype of Exception, so your attempt will also try to catch exceptions such as IndexOutOfBoundsException.
As others have noted, FileNotFoundException is never thrown by delete. Furthermore it is a checked exception. So the Java compiler will complain.

Because the type of error thrown doesn't match the one you're catching. Try this...
catch(Exception e) {
System.out.println("Exception: "+ e.getClass());
}
That will show you the type of error you should be catching. Obviously this isn't good practice but it's a good exercise for seeing what's happening. Other answers on this page concerning checked and unchecked exceptions are pretty concise.

If you look at the manual here delete() only throws a SecurityException.
Also, it returns a boolean value which indicates whether or not the file was deleted. This should be all the information needed to indicate to the user if everything worked out.

Isnt the message clear? As you dont construct a File object, a FileNotFoundException can never be thrown in this try block. Therefor the compilers informs you that the catch block in unneccessary.

Look for IOException. or deleteifExist method if you are not interested in the exception, if you want to retrn something, then file.exists() will help you fgure if the file is there or not.

Related

Second catch breaks compilation (first doesn't)

I have this code:
try {
// if (false) { //(need to add this, otherwise it doesn't compile)
// throw new CountDownExc(-1);
// }
return ad2;
} catch (StackOverflowExc | NoClassDefFoundError e) {
throw new CountDownExc(50);
} catch (CountDownExc e) {
if (!e.surfaced()) {
e.dec();
throw e;
}
return 0.0;
}
And if I don't add the commented code it doesn't compile with a:
error: exception CountDownExc is never thrown in body of corresponding
try statement
Why?
Most of all, why does the first catch doesn't cause the compiler to complain (but the second block seems to be wrong)
There is a couple of problems with your code:
First and foremost you need to understand the difference between checked exceptions and unchecked exceptions: Understanding checked vs unchecked exceptions in Java
Essentially you need to consider checked exceptions as part of your logic and you can only either rethrow them or handle them via catch. The only other option if you need to avoid catch( CountDownExc ) is to add a throws CountDownExc declaration to your method.
These lines make little sense to me:
} catch (StackOverflowExc | NoClassDefFoundError e) {
throw new CountDownExc(50);
It looks like you intend on catching two exception types in the first catch block, throw CountDownExc in that first catch block, then handle it in the second catch block. That's not gonna fly, because catch blocks handle what is thrown in a try block, not in a catch block. Since CountDownExc is a checked exception this is going to result in another compilation error, unless you either wrap your try-catch in another try-catch (bad practice) or add a throws declaration.
See: Exception thrown inside catch block - will it be caught again?
Since both of your catches throw CountDownExc the exception will have to be handled elsewhere anyway, so this may already be accounted for - I cannot tell, because the rest of your code is unknown.
Your immediate problem however comes from the fact, that nothing in your try block is able to throw CountDownExc and CountDownExc is a checked exception, see first link.

Catching undeclared CheckedException

I'm using a third-party java library and this library class has a method called doSomething:
Library.doSomething();
In the course of the doSomething method, it sometimes throws a java.net.SocketException, but the doSomething method does not declare the SocketException as a checked exception. So when I try to write:
try {
Library.doSomething();
} catch (java.net.SocketException error) {
error.printStackTrace(); // and do other recovery stuff
}
I get the following compiler error:
Unreachable catch block for SocketException. This exception is never thrown from the try statement body
However, I know that at runtime the doSomething method frequently throws the SocketException. I know that I can catch a generic java Exception and then check to see if it is a SocketException, but is there any more elegant way to catch the SocketExceptions thrown by this third party closed source library?
Thanks!
Edit - It turned out the SocketException is wrapped in a WebServiceException and I just missed the wrapped exception in a crowded error log. So there really isn't any question to answer. Sorry for the confusion.
Mena's answer is very good, but I just want to state that there are ways (4 of them if I recall correctly, I mention them in the comments) to throw check exceptions that are not declared.
As a solution I suggest catching something general like Exception and check the type of the caught exception (using instanceof is recommended).
You should write
catch (Exception e) {...}
Because compiler returns error if the catch block will never (or hardly ever) execute. In the catch block, you can compare the Exception using "instanceof" statement to get an information about specific exception.
I know that I can catch a generic java Exception and then check to see if it is a SocketException, but is there any more elegant way to catch the SocketExceptions thrown by this third party closed source library?
There is no alternative that will actually deal with the exception; i.e. allow you to actually handle it in the normal fashion.
Basically, the 3rd-party library has broken Java's checked exception rules. It is faulty and should be fixed.
FWIW, the code to work around the 3rd-party library bug is a "delicate":
try {
callNastyMethod();
} catch (Exception ex) {
if (ex instanceof SocketException) {
// handle the exception we are expecting
} else if (ex instanceof RuntimeException) {
// unexpected runtime exceptions should be rethrown
throw (RuntimeException) ex;
} else {
// deal with any other checked exceptions; for example.
throw AssertionError("Unexpected checked exception", ex);
}
}

This is about the Exception Handling and the Exception Matching Concept in Java

I am new to Java. I was going through the Exception Handling Concept but I stuck at one point here.
We know that whenever the Exception is thrown Java will try to find by looking at the available catch clauses in the top down manner. If it doesn't find one, it will search for a handler for a supertype of the Exception.If it does not find a catch clause that matches a supertype for the exception, then the exception is propagated down the call stack.
Also if most specific exceptions is placed above the more general exceptions handler then it results in the COmpilation error.
Suppose we have a code as shown below:-
try{
// do not know what kind of exception it will be throwing but I am sure that it is IOException
}
try{
// Here the FileNotFoundException is thrown
}
catch(IOException e){
//Do exception handling stuff
}
catch(FileNotFoundException f){
//Do exception handling stuff`
}
Now this code will result in the compilation error because the Supertype of the exception is present above the actual exception.
SO why the first paragraph do not support this concept. i.e After checking JVM will found the appropriate exception(FileNotFoundException) and should not bother about IOException clause, but run into compilation error instead.
Please throw some light on it.
Also let me know If I am able to explain what I want to??
It looks like you are misunderstanding the try concept. You only have one try followed by the catch clauses.
try{
// do not know what kind of exception it will be throwing but I am sure that it is IOException
// Here the FileNotFoundException is thrown
}
catch(IOException e){
//Do exception handling stuff
}
catch(FileNotFoundException f){
//Do exception handling stuff`
}
This code will throw an error at compile time because for FileNotFound Catch Block the code will be unreachable as it's already handled by IO Exception and FileNotFound is subclass for IOException
Unreachable catch block for FileNotFoundException. It is already handled by the catch block for IOException
FileNotFoundException is a subclass of IOException gives us the choice of either treating all IOExceptions the same, or catch some of IOExceptions subclasses individually
Code snippet has fundamental mistakes
If an exception occurs within the try block, that exception is handled by an exception handler associated with it. To associate an exception handler with a try block, you must put a catch block after it
Recommended reading:
https://docs.oracle.com/javase/tutorial/essential/exceptions/try.html
https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html

Which line in a long Java 'try' block is throwing an exception?

Is there a way to find out which line in a try block is throwing an exception?
I'm working on Java in Eclipse which looks like
try {
//Lots of code. Seriously. Lots.
} catch (Exception e){
throw new OtherException();
}
I'm hitting an exception in the try block, (which is then caught). How do I figure out where it's being thrown from?
Problems
The stack trace only shows the line in the catch block for the OtherException
Removing the try/catch block isn't straightforward, as there are many exceptions declared as thrown which are required to be caught in order for the code to compile.
It feels like there should be a straightforward way of doing this.
Note: I didn't write this code ;-)
Use the cause parameter for Exceptions (see here):
try {
//Lots of code. Seriously. Lots.
} catch (Exception e){
throw new OtherException(e); // Trick is here
}
This way you get the cause exception as well in the stacktrace.
You can use throw new OtherException(e);. As the documentation explains, this constructor constructs a new exception with the specified cause.
In Eclipse, you can set a breakpoint triggered by an exception. See Add Java Exception Breakpoint.
For this particular case, you'll need to ensure that "Suspend on caught exceptions" is ticked.
Once Eclipse breaks into the debugger, you'll have a lot of tools at your disposal. You'll see the call stack, will be able to examine variables etc.
Just print stacktrace or run on debug mode
e.printStackTrace()
Pass the exception e in your OtherException constructor when throwing it. It will give you the complete stack trace with the exact line throwing the exception:
catch (Exception e) {
throw new OtherException(e);
}
If OtherException doesn't have a constructor that takes an Exception or Throwable you could do:
catch (Exception e) {
OtherException o = new OtherException();
o.initCause(e);
throw o;
}
You can also try printing out the error message to the console: System.out.println(e.getMessage());
Breakpoints are very useful though, since you can then trace through the code and see exactly when it gets to the catch block.

Can an Error be handled?

public class StackTest {
public static void main(String[] args) {
show();
System.out.print("welcome back to maain");
display();
}
static void show(){
try{
show(); //recursion
}catch(StackOverflowError e){
System.out.print("error cought");
}
}
static void display(){
System.out.print("after stack overflow error");
}
}
In this program an StackOverflowError occurs but gets handled and the program does not terminated abnormally. why?
You can see this at http://ideone.com/vwSav
You can handle Errors because they are Throwable just like Exceptions.
Errors are designed to indicate problems outside your program's control, like OutOfMemoryError and StackOverflowError, but you can define your own errors, too.
Perhaps you are thinking that, or heard that, OutOFMemoryError can be caught but there's no guarantee you'll have enough space to execute the handler, so errors must in general not be something you can catch. In your case, though, you got away with it. No language rules were violated in the catching and handling of this error.
The real question is, should you catch them? Normally when an error, as opposed to an exception, is thrown, your application is very likely in an inconsistent state, making recovery a crapshoot at best. So be really, really careful. Better to forget it and let the app die though, since whatever is running after the handler is not guaranteed to be something you'd want to run.
Why would you expect it to terminate when you catch the exception (or rather the Error in this case)? What else would that catch block do?
You can catch and handle pretty much all error conditions, though usually you should only catch Exceptions.
You can catch any Throwable and it is up to the developer to handle it correctly. You can even handle ThreadDeath (triggered by a Thread.stop()) or another sub-class of Throwable (which is neither an Error or an Exception)
public class MyThrowable extends Throwable { } // checked "exception"
try {
throw new MyThrowable();
} catch (Throwable t) {
t.printStackTrace();
Thread.currentThread().stop(t); // rethrow blindly.
}
It will only be terminated abnormally if your exception is propagated all the way up to your main method and you don't handle it there. Usually happens for unchecked run time exceptions. If you want to terminate your program and shut down the VM you can call System.exit(int errorCode) in the catch block, there will be programmers which always complain here if that's done but that's a way to do it.
usually you don't catch Error, except for LinkageErrors, no class def found errors, unsatisfied link errors, incompatible class change errors..
also an outofmemory error (sometimes the stackoverflow exception) doesnot give control the catch block as there is no memory.

Categories

Resources