Should one always catch an IOException/Exception if a program reading in a txt file using a scanner object produces nothing but a FileNotFoundException?
Would such extra code be unneeded or important?
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TestingScanner {
public TestingScanner() {
readFile("dummy.txt");
}
public void readFile(String filePath) {
File file = new File(filePath);
Scanner scanner = null;
try {
scanner = new Scanner(file);
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.matches("^.+#yahoo\\.com?(\\.uk)?$"))
System.out.println(line);
}
} catch (FileNotFoundException e) {
System.out.println("ERROR: Couldn't Load in " + filePath);
e.printStackTrace();
} finally {
if (scanner != null)
scanner.close();
}
}
}
My rule of thumb is to go broad with exception catching (catching Exception or Throwable) unless there is something specific I will want do different for a specific exception.
For example, if a method throws two different Exceptions, and I will be handling both the same then I will just catch Exception. But if I am handling them different then I would catch each individually and process them accordingly.
The wrench in this approach is "what about RuntimeExceptions". One school of thought is to allow RuntimeExceptions to bubble up. But what I find is that in situations where I am catching exceptions, then I want all of them... and sometimes even Throwables (I got burnt once by only catching Exception and not Throwable).
Here are some examples:
public void myMethod() throws IOException, FileNotFoundException ();
In situation where I want to not let Exceptions bubble up (need to deal with them all)
try{
myMethod();
catch(Exception e) {
//handle it
}
In situation where I am catching Exceptions and need to do something different for FileNotFound.
try{
myMethod();
catch(FileNotFoundException fe){
//handle file not found
}
catch(Exception e) {
//handle it
}
In situation where I am letting Exceptions bubble up because I know further up the chain some really cool exception handling code is handling it and I want to avoid logging the exception multiple times:
myMethod();
In situation where I am letting Exceptions bubble up except for FileNotFound.
try{
myMethod();
catch(FileNotFoundException fe){
//handle file not found
}
You can use throws Exception instead, but it is advised to do try/catch since you can tell your program what to do in case of error. And yes, it is necessary to have exceptions in case there is an error.
Yes, we must always catch the IO Exceptions. Since IO is related to reading or writing to a file, there is always a chance that it might fail due to various reasons(wrong input path, unavailability of resource, network failure).
After catching the exception we should always log the exception.
In big projects these exception logs helps in identifying the actual cause for some functionality failure.
Related
I am learning how to create file and directory in java using this code.
On the ERROR LINE I am getting error as "IOException is never thrown in this block".
So how do I know which function is throwing what type of Exception?
Or if I am not sure I should use generic Exception in every catch block.
public class FileTest {
public static void main(String[] args) {
//file creation
boolean flag = false;
File file = new File("/IdeaProjects/JavaCode/jstest.txt");
try {
flag = file.createNewFile();
}catch (IOException e){
e.printStackTrace();
}
System.out.println("file path is : " + file.getPath());
//dir creation
boolean dirFlag = false;
File fileDir = new File("/IdeaProjects/JavaCode/js");
try{
dirFlag = fileDir.mkdir();
}catch (IOException e){//ERROR LINE
e.printStackTrace();
}
if(dirFlag)
System.out.println("created");
else
System.out.println("exist");
}
}
The java.io.File#mkdir method only declares to throw SecurityException - see API.
java.lang.SecurityException is a RuntimeException and doesn't require being caught, although you may want to, depending on the context (again, see API).
Catching general java.lang.Exception in every catch block is absolutely not a recommended practice, although you may sometimes have to (not in your present case though).
See here for some SO literature on the matter.
Remember what methods throw exceptions and which exceptions they are.
Check the documentation if you think a method may throw an exception.
Just attempt to compile the code and fix the errors the compiler throws (They will tell you what exceptions are thrown by what method if the try-catch block is missing).
The method in question (File.mkdir()) throws a SecurityException which doesn't need to be caught (you can if need be) as it is an unchecked RuntimeException.
java.io.File: https://docs.oracle.com/javase/7/docs/api/java/io/File.html#mkdir()
SecurityException: https://docs.oracle.com/javase/7/docs/api/java/lang/SecurityException.html
Quoting JLS Section 11.2:
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.
If no method you invoke in the try block declares that it throws IOException (and you don't throw new IOException(..) directly either), it is a compile-time error if you try to catch an IOException.
In GraphicsFileNotFoundException.java all I have is an import of FileNotFoundException and the class GraphicsFileNotFoundException which extends FileNotFoundException.
In my main java file, I'm trying to read in a graphics file with the method getGraphicsFile which throws GraphicsFileNotFoundException.
My brain is pooped after a good 40 minutes trying to find out how to catch this exception. I've tried using a try-catch block and catching GraphicsFileNotFoundException but I still get the error
unreported exception GraphicsFileNotFoundException ; must be caught
or declared to be thrown.
public void getGraphicsFile(String fileName) throws GraphicsFileNotFoundException {
String graphics = "";
Scanner getGraphics = null;
try {
getGraphics = new Scanner(new File(fileName));
}
catch (GraphicsFileNotFoundException e){
System.out.println("Error! File can't be found :/");
}
You need to either properly extend the FileNotFoundException class or manually throw an exception inside your try block.
Assuming this is for an assignment (I'm not sure why else you'd need to specifically extend this exception) you'll need to take another look at your GraphicsFileNotFoundException class and make sure that it does what it needs to.
To throw an exception, simply write your condition and the throw statement:
if(needToThrow) {
throw new GraphicsFileNotFoundException();
}
To catch an exception, surround the throw statement with a try block immediately followed by a catch block.
try {
// code here
if(needToThrow) {
throw new GraphicsFileNotFoundException();
}
}
catch(GraphicsFileNotFoundException e) {
// handle the error (print stack trace or error message for example)
e.printStackTrace(); // this is printing the stack trace
}
I recommend using Eclipse if you aren't already because many times it will offer to surround throw statements that need to be caught with a automatically generated try catch block.
so I have a bit of code here and I'm not sure entirely how it would react in the event that the reader.close() method throws an exception.
public void someMethod(String s) throws IOException{
BufferedReader reader = Files.newBufferedReader(filePath,cs);
listRWLock.readLock().lock();
try{
//miscellaneous code involving reading
}finally{
reader.close()
listRWLock.readLock().unlock()
}
}
ListRWLock is a ReentrantReadWriteLock. In the event that the reader.close() method throws an exception, would the statement after it fail to execute? I've tried searching for the topic, and while I've gotten something about finally executing in the event of return statements, I haven't managed to find details on what happens if an exception is thrown within the finally block.
Thanks in advance.
Basically, finally clauses are there to ensure proper release of a resource. However, if an exception is thrown inside the finally block, that guarantee goes away.
An issue for which there's no really neat solution is that code in the finally block could itself throw an exception. In this case, the exception in the finally block would be thrown from the exception instead of any exception occurring inside the try block. Since code in the finally block is intended to be "cleanup" code, we could decide to treat exceptions occurring there as secondary, and to put an excplicit catch:
public int readNumber(File f) throws IOException, NumberFormatException {
BufferedReader br = new BufferedReader(new
InputStreamReader(new FileInputStream(f), "ASCII"));
try {
return Integer.parseInt(br.readLine());
} finally {
try { br.close(); } catch (IOException e) {
// possibly log e
}
}
}
Some other things to note about finally blocks:
The same 'overriding' problem that we mentioned with exceptions
occurs when returning a value from a finally block: this would
override any return value that the code in the try block wanted to
return. In practice, returning a value from a finally clause is rare
and not recommended.
Actually exiting the program (either by calling System.exit() or by
causing a fatal error that causes the process to abort: sometimes
referred to informally as a "hotspot" or "Dr Watson" in Windows)
will prevent your finally block from being executed!
There's nothing to stop us nesting try/catch/finally blocks (for
example, putting a try/finally block inside a try/catch block, or
vice versa), and it's not such an uncommon thing to do.
You can do something like this:
try{
//miscellaneous code involving reading
}finally{
handlePossibleException(reader);
listRWLock.readLock().unlock()
}
handlePossibleException(BufferedReader reader) {
try {
if (reader != null) {
reader.close();
}
} catch( Exception e ) {
log.e( "reader.close() Exception: ", e );
}
}
You should test this,
but if try throws IO Exception, then your reader wont close.
Maybe have
catch(IOException ex){
reader.close()
An exception can happen anywhere in your code, including finally block, so you have to catch it as anywhere else in your code. Check the following post to get some ideas about the ways you can handle such situation:
throws Exception in finally blocks
I have a method that throws an Exception, which calls a method which throws an Exception, etc etc. So several methods that "throw Exception" are daisy-chained.
The first method that calls the submethod, puts that submethod in a try-catch block that catches any Exception that gets thrown inside that call. IN THEORY. In practice, no Exception is being caught by that try-catch block. Is there a way to remedy that?
Here is the code:
try {
CSVSingleton.tryToReadBothFiles(FILE1_PATH, FILE2_PATH);
} catch (Exception e) { // THIS BLOCK NEVER GETS ENTERED BY THE PATH O EXECUTION
System.out.println("There was an exception reading from at least one of the files. Exiting.");
System.exit(0);
}
here is the method from the CSVSingleton class:
public static void tryToReadBothFiles(String filePath1, String filePath2) throws Exception {
file1 = new CSVFileForDwellTime1(filePath1);
file2 = new CSVFileForDwellTime2(filePath2);
}
And here is code from the CSVFileForDwellTime1 class:
public CSVFileForDwellTime1(String filePath) throws Exception {
super(filePath);
}
and then here is the code that actually throws an original FileNotFoundException:
public GenericCSVFile(String filePath) throws Exception{
this.filePath = filePath;
try {
fileReader = new FileReader(filePath);
csvReader = new CSVReader(
fileReader);
header = getActualHeaderNames();
} catch (FileNotFoundException e) {
System.out.println("Could not read file with name: " + filePath);
// e.printStackTrace();
}
}
My guess is that the FileNotFoundException in the last method is caught by the catch block and so doesn't "bubble up". But is there a way to force it to bubble up?
Immediate answer:
Your thought is exactly right,
try {
fileReader = new FileReader(filePath);
csvReader = new CSVReader(
fileReader);
header = getActualHeaderNames();
} catch (FileNotFoundException e) {
System.out.println("Could not read file with name: " + filePath);
// e.printStackTrace();
}
This suppresses the exception
Either remove the try-catch block (desired unless you can actually do something with the exception)or re-throw it within the catch block.
Explanation
Generally with checked exceptions like this you have 2 options
Catch the exception and do something to remedy the exception
Throw the exception to the caller
What you have done here falls into the 1st category except that you have not done anything useful in the catch block (printing to console is rarely useful in this case because the exception message itself normally has enough information to see what has gone wrong)
The 2nd category is achieved either by not using a try-catch block and thus adding throws FileNotFoundException to the method signature. Alternatively explicitly throw the exception that you caught using:
catch(FileNotFoundException e)
{
//do something
throw e;
}
however in this case if do something isn't worthwhile you have unnecessarily caught something just to throw it on.
You can think of it like this:
Alice throws a ball to Charlie
Bob intercepts the ball
Bob then looks at the ball and then throws it to Charlie
Bonus Points
When you know the exception that could occur make sure to actually catch or throw that exception and not a parent of that exception.
Take the following method signatures for example:
public String method1() throws Exception
public String method2() throws FileNotFoundException
Here method2 clearly tells the caller what could happen and can help then figure out why the exception is being called (without having to read through the code or experience the error).
Secondly other exceptions can occur and you are potentially catching the wrong exception, take the following example:
try{
fileReader = new FileReader(filePath); //could potentially throw FileNotFoundException
fileReader = null; //woops
csvReader = new CSVReader(fileReader); //throws NullPointerException but the compiler will not know this
//....other stuff....//
}
catch(Exception e){
// the compiler told me that a FileNotFoundException can occur so i assume that is the reason the catch has executed
System.err.println("You have entered an invalid filename");
//doing anything here that would fix a FileNotFoundException is pointless because that is not the exception that occured
}
Use a throw in the catch clause.
} catch (FileNotFoundException e) {
System.out.println("Could not read file with name: " + filePath);
// Continue up, Mr. Exception!
throw e;
}
Alternatively, wrap the exception as appropriate (since an IOException is checked this handy here) - this is called a Chained Exception. Then, depending on what is thrown, the throws Exception can be removed from the method signature.
throw new RuntimeException("Could not read file: " + filePath, e);
If you don't want to catch it, then don't. Alternatively, you can just throw it again with a throw-statement. You can also throw a new Exception of any class you like. You should only catch an Exception at a level where you can react to it properly. As you found out, catching it at that low level is not helpful, so do not catch it there.
You can rethrow the exception once you catch it, for callees further up the stack to handle. You can change what exception it is too if a new type of exception makes more sense at a higher level.
catch (SomeSpecificException e)
{
some code here
throw new AMoreBroadException("I really need the callee to handle this too");
}
Technically you just need to add throw e right after System.out.println("Could not read file with name: " + filePath); and the exception will propagate up to the first method.
However, this would not be a clean way to handle the exception, because in this case all you'd be doing is printing an error message at the cost of changing the location of the original FileNotFoundException. Ideally, when you need to inspect an exception stacktrace, you expect a line of code throwing an exception to be the actual line that really caused the exception.
The throws Exception in the method declaration should be considered part of the contract of the method, i.e. it describes a possible behavior of the method. You should always ask yourself: Does it make sense for a FileNotFoundException to be specified as a possible exceptional behavior for the method/constructor I'm writing? In other words, do I want to make the caller of my method aware of this exception and leave it to the caller to deal with it? If the answer is yes (and in this case I would say it makes sense), then avoid wrapping the code in a try-catch block. If no, then your catch block should be responsible for dealing with the exception itself. In this specific example IMO there is not much you can do in the catch statement, so just remove the try-catch.
As mentioned by others, you should declare the most specific exception in the method signature (throws FileNotFoundException instead of throws Exception).
I'm currently working on an assignment (Java) for school. In the instructions/rubric, I'm told that I need to use I/O Exception Handling for command line arguments and other things.
**What The Program Needs to do: **
Take two command line arguments when it runs, or else throw an error.
The rubric includes this requirement : "I/O error handling is done if no command arguments"
The problem is, every time I try to use an I/O exception catch, I receive this error:
"Unreachable catch block for IOException. This exception is never thrown from the try statement body"
The quick fix suggestions I get from Eclipse:
1. Remove Catch clause
2. Replace Catch clause with close
Here is my Code:
import java.awt.Robot;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
public class DecipherText {
public static void main(String[] args) throws IOException {
String firstArg;
String secondArg;
if (args.length > 0) {
try {
firstArg = args[0];
secondArg = args[1];
} catch (IOException e) {
System.out.println("Usage Error: Not enough Arguments");
System.out.println(e);
return;
}
}
String inputFile = args[0];
String outputFile = args[1];
}
public static boolean receiver() {
return false;
}
public static boolean output() { // Outputs The Final File
return false;
}
}
My question(s) are:
If so, what am I doing wrong?
Is this requirement impossible/asking for the wrong usage of the I/O Error exception handling?
Any help is greatly appreciated.
Thanks,
Sully
I think the problem is that Java will never throw an IOException in the code
firstArg = args[0];
secondArg = args[1];
therefore, there is no need to catch an IOException. An exception you might catch could be ArrayIndexOutOfBoundsException if the user didn't provide 2 arguments.
IOException is sometimes thrown when you're communicating with outside sources such as through a Socket, or reading from a File and some reading of input goes wrong. But determining what's in the args array does not throw an IOException.
I'm not quite sure why your teacher specified I/O Exception. Does he mean input output in general or the Java IOException?
the reason its saying that is because there isn't any operation going on inside the try block that can possible throw IOException. in other words, there's no way you can get IOException from what's inside your try block. You can try catching ArrayIndexOutOfBoundsException since that can potentially happen in which case also remove the if(args.length > 0) as its no longer needed since you will be catching that error and handling it. Hope this helps.
You could use just this code in case theres no IOException, it will stop error, it just wont give an IO if there is one.
try {
} catch (Exception e) {
}