Difference between catching exceptions using Exception class or FileNotFoundException class - java

Like i have these two scenarios where we have to handle FileNotFoundException
Case1:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Case2:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (Exception e) {
e.printStackTrace();
}
In both cases printed Stack Trace is same. I would like to know the difference between both implementations and what should be preferred ?

From the docs it gives the reason:
"A subclass inherits all the members (fields, methods, and nested
classes) from its superclass. Constructors are not members, so they
are not inherited by subclasses, but the constructor of the superclass
can be invoked from the subclass."
Exception class is the parent of all the other exception class. So if you know that you are going to get the FileNotFoundException then it is good to use that exception. Making the Exception is a generic call.
This would help you understand:
So as you can see that the Exception class is at a higher hierarchy, so it means it would catch any exception other than the FileIOExcetion. But if you want to make sure that an attempt to open the file denoted by a specified pathname has failed then you have to use the FileIOExcetion.
So here is what an ideal approach should be:
try {
// Lets say you want to open a file from its file name.
} catch (FileNotFoundException e) {
// here you can indicate that the user specified a file which doesn't exist.
// May be you can try to reopen file selection dialog box.
} catch (IOException e) {
// Here you can indicate that the file cannot be opened.
}
while the corresponding:
try {
// Lets say you want to open a file from its file name.
} catch (Exception e) {
// indicate that something was wrong
// display the exception's "reason" string.
}
Also do check this: Is it really that bad to catch a general exception?

In case 2, the catch block will be run for all Exceptions that are caught, irrespective of what exception they are. This allows for handling all exceptions in the same way, such as displaying the same message for all types of exceptions.
In case 1, the catch block will be run for FileNotFoundExceptions only. Catching specific exceptions in different catch blocks allows for the handling of different exceptions in different ways, such as displaying a different message to the user.

When an exception occures the JVM throws the instance of the Exception and that instance is passed to the respective catch block , so in catch(Exception e) e is just the reference variable , but the instance it points to is of Exception thrown .
In case of catch(FileNotFoundException e) , e is also a reference variable and the instance it points to is of Exception thrown , so in both cases different reference varibales (i.e. e) are pointing to the instance of same the Exception (which is thrown) .
this is what i prefer :
try {
// some task
} catch (Exception e) {
if (e instanceof FileNotFoundException) {
// do this
}
if (e instanceof NullPointerException) {
// do this
} else {
// do this
}
}

It is a matter of what you want to intercept. With Exception you will catch any exception but with FileNotFoundException you will catch only that error case, allowing the caller to catch and apply any processing.

When you write this:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
The code inside the catch block is only executed if the exception (thrown inside the try block) is of type FileNotFoundException (or a subtype).
When you write this, on the other hand:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (Exception e) {
e.printStackTrace();
}
the catch block is executed for any exception (since Exception is the root type of any exception).
If your file (test1.txt) does not exist, a FileNotFoundException is thrown and both code snippets are able to catch it.
Try and change it to something like:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (NullPointerException e) {
e.printStackTrace();
}
and you will see that the catch block is no longer executed.

Exception class is the parent of FileNotFoundException.
If you have have provided the Exception in the catch statement, every Exception will be handled in the catch block. But if FileNotFoundException is present in catch block, only exceptions rising due to absence of a File at said source or permissions not available to read the file or any such issues which makes spoils Java's effort to read the file will be handled. All other exceptions will escape and move up the stack.
In the code snippet provided by you, it is fine to use both. But i would recommend FileNotFoundException as it points to exact issue in the code.
For more detail you can read Go Here

Don't use any of those.
Don't catch Exception. Why? Because it also catches all unchecked exceptions (ie, RuntimeExceptions and derivates). Those should be rethrown.
Don't use the old file API. Why? Because its exceptions are unreliable (FileNotFoundException can be thrown if you try and open a file to which you have no read access to for instance).
Use that:
final Path path = Paths.get("test1.txt");
try (
final InputStream in = Files.newInputStream(path);
) {
// do something with "in"
} catch (FileSystemException e) {
// fs level error: no permissions, is a directory etc
} catch (IOException e) {
// I/O error
}
You do need to catch FileSystemException before IOException since the former is a subclass of the latter. Among other possible exceptions you can have: AccessDeniedException, FileSystemLoopException, NoSuchFileException etc.

Related

Why is it allowed to catch subtype of a thrown exception in Java

I read in a Java book, that "Java will not allow you to declare a catch block for a checked exception type that cannot potentially be thrown by the try class body".
That makes sense so far.
But now I am asking myself why this code does compile:
try {
throw new Exception();
} catch (IOException e) {
} catch (Exception e) {
}
Java allows me to catch the IOException, but obviously it will never be thrown by the try-block.
Doesn't this example break the rule described in the Java book?
Java allows me to catch the IOException, but obviously it will never
be thrown by the try-block.
Because Exception is more general than IOException so the compiler understand that Exception can also be IOException.
Here is a contre example of what will happen if you try NumberFormatException instead of Exception
try {
throw new NumberFormatException();
} catch (IOException e) { // fail
} catch (Exception e) {
}
It fail because NumberFormatException is not general than IOException.
It is obvious to a programmer that reads this code, but i guess the compiler will deal with the throw statement the same way it would deal with a call to a method declared as throwing Exception, and in this case, the thrown exception could very well be an IOException.

Should I re-throw an exception after logging it?

I find myself coding methods that throw a specified error, but still surrounding the relevant code sections in a try catch, where I use the catch to log a localised error message and re-throw the principal one.
Here is a short example:
public void doWork(String url) throws IOException {
Object target;
try {
target = new target(url); //instantiating this object could potentially not work if the URL is malformed
} catch (MalformedURLException e) {
localErrorMessage(debug, "URL error here"); //log a local message
throw e;
} catch (IOException e) { //in some cases it can throw an IO exception if using a localised file type object.
localErrorMessage(debug, "IO error here"); //log a local message throw e;
}
}
I use this as I can turn off my localised logging (using log4j2), or use it during testing, as a debugging method.
Is this a reasonable practice, or is there a better way to do it?

How to handle multiple exceptions in a java method?

I've read It isn't a best practice to handle multiple Exceptions like this:
public void myMethod() throws ExceptionA, ExceptionB, ExceptionC {
//more code here
}
And then to call myMethod():
try {
myObject.myMethod();
} catch(Exception e) {
//More code here
}
Despite Exception is the parent class of all the other exceptions, it is consider a bad practice. But, in my application I'm using java SE 6 and I need to:
Do File operations that can imply a FileNotFOundException and IOException
Marshal objects (in order to create XML files) JAXBException
Create a pdf file (using pdfbox library) COSVisitorException
Send an email using JavaMail, MessagingException
The easiest way is to add a throws statement in method declaration, but what could be the proper way to write the client method?
Is it OK to add 6 or 7 catch blocks to handle all the possible exceptions?
Generally speaking (for Java 6 and below), you should handle each exception individually...
try {
myObject.myMethod();
} catch (ExceptionA e) {
// Condition for A
} catch (ExceptionB e) {
// Condition for B
} catch (ExceptionC e) {
// Condition for C
}
This allows you to handle each exception differently based on what it is, but also means you are only handling those exceptions reported to be thrown by the method
In Java 7+ you can make use of "multi-catch" or "combined catch" (we can't find an "official" term)
try {
myObject.myMethod();
} catch (ExceptionA | ExceptionB | ExceptionC e) {
// Condition for A and B and C
}
But even then, you should be focusing exceptions into "common" use groups
try {
myObject.myMethod();
} catch (ExceptionA | ExceptionB e) {
// Condition for A and B
} catch (ExceptionC e) {
// Condition for C
}
Another option, if you control how the exceptions are defined, is to extend from a common base exception, a good example of this is the FileNotFoundException which extends from the IOException, which is thrown by FileReader and FileInputStream (as examples), this means you can handle the FileNotFoundException as a common IOException should you wish...
FileReader fr = null;
try {
fr = new FileReader(new File(...));
// Read from reader...
} catch (IOException exp) {
// Common catch block
} finally {
// Best attempt to close
try {
fr.close();
} catch (Exception exp) {
}
}
Or you could handle the FileNotFoundException as it's own condition...
FileReader fr = null;
try {
fr = new FileReader(new File(...));
// Read from reader...
} catch (FileNotFoundException exp) {
// File not found condition
} catch (IOException exp) {
// Other IO condition
} finally {
// Best attempt to close
try {
if (fr != null) {
fr.close();
}
} catch (Exception exp) {
}
}
This allows you to either group "like" exceptions together, but also provides you with the control to define more fine grained conditions should you need to...
Beware though, we the above example, if I put the IOException first, the FileNotFoundException would never be handled, when doing this, make sure that you use the lowest/tightest/finest exceptions first, as they are processed sequentially in the order you have listed
Another option (which I'm not keen on, but have seen) might be to catch a "common" ancestor and then compare the actual type, which would allow you to provide common handlers for some sub-type of the exception.
} catch (IOException exp) {
if (exp instanceof FileNotFound || exp instanceof FileSystemException) {
// Common handling
} else {
// Generic handling
}
}
This might be helpful in situations where the method only throws the ancestor type (ie IOException), but you need to provide a more fine grained resolution
But, again, I would be focused on only handling the expected "common" exceptions declared as been thrown, don't be tempered to catch Throwable for example

Is this pattern for handling IO exceptions in Java correct?

In the following code snippet, if ex1 is thrown, will be be caught by the second catch block, or will it be thrown back to the caller of the method?
And if it is thrown back to the caller, and then a second exception occurs in the finally block (ex2), does that mean 2 exceptions will be thrown back to the caller (ex1 and ex2)?
try {
// write to file
} catch (IOException ex1) {
throw ex1;
} finally {
try {
aBufferedWriter.close();
} catch (IOException ex2) {
throw ex2;
}
}
Both of those exceptions would be thrown back to the caller... although a single exception in any particular situation. If the body of the outer try block throws and then close throws as well, only the second exception would be seen by the caller.
However, having a catch block just to rethrow is pointless. Your code would be clearer as:
try {
// write to file
} finally {
aBufferedWriter.close();
}
In Java 7, a try-with-resources statement can do that automatically:
try (BufferedWriter writer = new BufferedWriter(...)) {
// Use the writer here
} // The writer is auto-closed here
That way you can also get at an exception on close separately from an exception in the main body, using Throwable.getSuppressed.
Depends on the design. You can also try
try{
try{
//write to file
}finally{
aBufferedWriter.close();
}
}catch(IOException e){
}
Also why catch the exception if you want to throw it.
Q. In the following code snippet, if ex1 is thrown, will be be caught by the second catch block, or will it be thrown back to the caller of the method?
No, it won't be caught by the catch block inside the finally, provided there is no exception in the finally block and thus the exception ex1 would be thrown back to the caller method.
Q. And if it is thrown back to the caller, and then a second exception occurs in the finally block (ex2), does that mean 2 exceptions will be thrown back to the caller (ex1 and ex2)?
In this case, since a exception gets thrown in the finally block, it'll overwrite the exception thrown in the outer catch block and resulting in the exception ex2 getting thrown back to the caller method.
Only either of the exceptions would be thrown back to the caller method for a single execution of this, not both. That being said, having a catch block just to throw back the exception which has been caught, is really pointless.
Before Java 7, the really accurate pattern was
public void writeToFile(String file) throws IOException {
IOException exception = null;
OutputStream out = new FileOutputStream(file);
try {
// TODO: write data to file
} catch (IOException ex) {
// store exception for later rethrow
exception = ex;
} finally {
try {
out.close();
} catch (IOException ex) {
// do NOT supress 'outer' exception:
if (exception == null) {
exception = ex;
}
}
}
if (exception != null) {
throw exception;
}
}
Looks crazy, but this covers every possibility and circumvents exception supressed exceptions (when an exception is thrown in the finally statement, it supresses the 'real' exception that happened in the try block - if any).
But maybe - for the sake of readability - you can live with suppressed exceptions and do it like that:
OutputStream out = new FileOutputStream(file);
try {
// TODO: write data to file
} finally {
out.close(); // if an exception is thrown here, it hides the original exception
}
See also http://tutorials.jenkov.com/java-exception-handling/exception-handling-templates.html
Since Java 7, you can do (almost) the same with a try-with-resource statement:
public void writeToFile(String file) throws IOException {
try (OutputStream out = new FileOutputStream(file)) {
// TODO: write data to file
}
}
Note that exceptions that are thrown when the resource is closed do NOT suppress the original exception. Instead this additional exceptions are added as 'suppressed exceptions' to the base exception. You can get them with baseException.getSuppressed() (Java 7 and above!).
See also http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Capture Run Time Errors Java

I am sure this must have been asked earlier, but I couldn't search the post.
I want to capture run time errors generated by thread with native java libraries, what methods can I use to do same ?
Here's an example of error :
Exception in thread "main" java.io.FileNotFoundException: C:\Documents and Settings\All Users\Application Data\CR2\Bwac\Database\BWC_EJournal.mdb (The system cannot find the path specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at java.io.FileInputStream.<init>(FileInputStream.java:66)
at CopyEJ.CopyEJ.main(CopyEJ.java:91)
I want to log this error in file to be reviewed later
Just catch the exception! My guess is that currently your main method is declared to throw Exception, and you're not catching anything... so the exception is just propagating out of main. Just catch the exception:
try {
// Do some operations which might throw an exception
} catch (FileNotFoundException e) {
// Handle the exception however you want, e.g. logging.
// You may want to rethrow the exception afterwards...
}
See the exceptions part of the Java tutorial for more information about exceptions.
The fact that the exception came up in native code is irrelevant here - it's propagated in a perfectly normal way.
Thread class has 'uncaught exception handler' - see http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setUncaughtExceptionHandler%28java.lang.Thread.UncaughtExceptionHandler%29. It allows you to delegate exception handling to somewhere outside of your thread, so you don't need to put try-catch in your run() method implementation.
You can catch errors with the try block.
Example
try {
// some i/o function
reader = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
// catch the error , you can log these
e.printStackTrace();
} catch (IOException e) {
// catch the error , you can log these
e.printStackTrace();
}
Java Tutorials- Lesson: Exceptions
its good practices use try catch and finally
try {
//Your code goes here
} catch (Exception e) {
//handle exceptions over here
} finally{
//close your open connections
}

Categories