Type of Exception in catch block - java

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.

Related

Catching thrown exceptions with an Exception class I created

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.

The need to catch IOExceptions & Exceptions

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.

In Java, how to force an Exception to "bubble up"?

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).

Can I set Eclipse to ignore "Unhandled exception type"

Is it possible to get Eclipse to ignore the error "Unhandled exception type"?
In my specific case, the reason being that I have already checked if the file exists. Thus I see no reason to put in a try catch statement.
file = new File(filePath);
if(file.exists()) {
FileInputStream fileStream = openFileInput(filePath);
if (fileStream != null) {
Or am I missing something?
Is it possible to get Eclipse to ignore the error "Unhandled exception type FileNotFoundException".
No. That would be invalid Java, and Eclipse doesn't let you change the rules of the language. (You can sometimes try to run code which doesn't compile, but it's not going to do what you want. You'll find that UnresolvedCompilationError is thrown when execution reaches the invalid code.)
Also note that just because the file existed when you called file.exists() doesn't mean that it still exists when you try to open it a tiny bit later. It could have been deleted in the meantime.
What you could do is write your own method to open a file and throw an unchecked exception if the file doesn't exist (because you're so confident that it does):
public static FileInputStream openUnchecked(File file) {
try {
return new FileInputStream(file);
} catch (FileNotFoundException e) {
// Just wrap the exception in an unchecked one.
throw new RuntimeException(e);
}
}
Note that "unchecked" here doesn't mean "there's no checking" - it just means that the only exceptions thrown will be unchecked exceptions. If you'd find a different name more useful, then go for it :)
Declare that it throws Exception
Or put it in a try finally bolok
Here it is sir:
try
{
file = new File(filePath);
if(file.exists()) {
FileInputStream fileStream = openFileInput(filePath);
if (fileStream != null) {
// Do your stuff here
}
}
}
catch (FileNotFoundException e)
{
// Uncomment to display error
//e.printStackTrace();
}
You cannot ignore that as it is not due to Eclipse, it is a compiler error, your code will not compile without your calls being enclosed in a try/catch clause. You can, however, leave the catch block empty to ignore the error although it is not recommended...

Java catching exceptions and subclases

Hello,
In Java if a method like BufferedReader.read() says it can throw an IOException and I try to catch a FileNotFoundException and an IOException in two catch blocks, what catch blocks will be entered if the file doesn't exist?
Does it enter only the most specific or both?
The first coded catch that matches the exception will be entered.
Edited to incorporate comment from Azodius
For example:
try {
bufferedReader.read();
} catch (FileNotFoundException e) {
// FileNotFoundException handled here
} catch (IOException e) {
// Other IOExceptions handled here
}
This following code does not compile:
try {
bufferedReader.read();
} catch (IOException e) {
// All IOExceptions (and of course subclasses of IOException) handled here
} catch (FileNotFoundException e) {
// Would never enter this block, because FileNotFoundException is a IOException
}
Compiler message says:
Unreachable catch block for FileNotFoundException. It is already handled by the catch block for IOException
Only the first catch block encountered where the exception type of the catch block matches the type of the exception being thrown will be run (more specifically, the first catch block where (e instaceof <exception type>)==true will be run). None of the other catch blocks will be run.
For example
try{
BufferedReader.read();
}
catch(FileNotFoundException e){System.out.println("FileNotFoundException");}
catch(IOException e){System.out.println("IOException");}
Will print FileNotFoundException if BufferedReader.read() throws a FileNotFoundException.
Note that the following doesn't actually compile:
try{
BufferedReader.read();
}
catch(IOException e){System.out.println("IOException");}
catch(FileNotFoundException e){System.out.println("FileNotFoundException");}
because Java realizes that it is not possible for the FileNotFoundException to be caught because all FileNotFoundExceptions are also IOExceptions.
The first one which is suitable for that type of exception (and only that). So if you catch the two exception types above in the order you list them, a FileNotFoundException will be caught.
Specific exception is caught first. and it's a compile time error if generic exception is caught befor specific one.

Categories

Resources