I can't seem to phrase this correctly for the search engine to pick up any meaningful results.
try{
BufferedReader reader = new BufferedReader( new FileReader("foo.bar") );
}
catch(Exception e){
println( e.getMessage() );
}
So FileReader only throws the FileNotFoundException, which as I understand it is an IOException, which is an Exception. Can someone explain why I would catch FileNotFoundException or IOException instead of just specifying the generic "Exception" and not having to import an exception (i.e. import java.io.FileNotFoundException;)? Is it strictly for readability?
I've caught the exception using all three names and I can't find a difference.
EDIT:--------------------
private BufferedReader askUserForFile(String prompt){
BufferedReader rd = null;
while(rd == null){
try{
String filename = readLine(prompt);
rd = new BufferedReader( new FileReader(filename) );
}
catch(Exception e){
println(e.getMessage());
}
}
return rd;
}
Exception is the mother of all exceptions, including all RuntimeException subclasses. When you specify to catch it, you'll get much more fish in the net than you wanted, like NullPointerExceptions, IllegalArgumentExceptions and so on.
While catching the generic Exception is the right thing to do at some point in your code, catching it at any lower layer is almost certainly wrong and can hurt the behavior of your application.
The more important skill to learn in Java is not how to catch exceptions, but how to not catch them, instead letting them propagate up the call stack, towards the exception barrier, the one common spot in the code where all errors are caught and uniformly handled (typically by logging, rolling back the transaction, and similar).
The difference is there could be other problems inside the code of your try block that could throw other types of Exceptions including subclasses of RuntimeException (which don't have to be declared).
If you just catch Exception, then you will catch all of those other errors too which may hide a different problem. Also your code inside the catch block can't assume the Exception happened due to an IOException since any kind of exception will be caught.
As a followup to dkatzel's answer, let's assume you start to read from the file in the same try block and the file tells you which value in a array of options to use:
String toPrint = {"Hi", "World", "I'm", "A", "String", "Array"};
try{
BufferedReader reader = new BufferedReader( new FileReader("foo.bar") );
String line = reader.readLine();
System.out.println(toPrint[Integer.parseInt(line)]);
}
catch(Exception e){
println( e.getMessage() );
}
Now you have absolutely no idea what really went wrong except through the stack trace. You can't handle any fixable problems. You can't tell in code whether the file doesn't exist (FileNotFoundException), you don't have access to the file, (IOException), if the first line wasn't an Integer (NumberFormatException), or the number was bigger than the array length (ArrayIndexOutOfBoundsException). If you wanted to print a default value if you couldn't read the number, you could instead catch a NumberFormatException and print the value instead of having to quit the entire program.
I'll admit this is a pretty contrived example, but it should give you an explanation of why catching Exception is bad. Marko also has a very good answer, stating that it usually is better to let the exception propagate up (especially with RuntimeExceptions) than to create a bunch of messy code trying to deal with every single problem that can happen.
What if you want to do a different action with different exceptions? You can make a catch block for IOException and for example, make it show a message box. Then make another catch block for a FileNotFoundException and make it create a new file and try to open it again, or even rethrow the exception. Hope I explained myself correctly. Cheers!
The reason is whenever you program, you have to think about all the possibilities and it is useful to do something for a specific error. Exception is a catch all method of catching errors and will handle all exceptions the same. IOException will catch any IO Exceptions so it will treat file not found and and other IO Exception (like EOFException) the same. FileNotFoundException will only catch file not found exceptions so you can handle it instead of just logging it.
Some errors will happen and being able to handle each individual case keeps your program running. In this case, file not found can make you select another file so the program doesn't crash and it handles the situation.
FileNotFoundException is an IOException which is an Exception
You are right. But if you catch Exception objects you will catch any exception triggered by your code, not only the FileNotFound exception.
Let's say that your code can throw more than one kind of exception:
try {
/*
* Code, code and more code
*/
} catch(ExceptionType1 e) {
System.err.println("Something went wrong! It is a type 1 exception");
} catch(ExceptionType2 e) {
System.err.println("Something went wrong! It is a type 2 exception");
} catch(Exception e) {
System.err.println("Something went wrong! It is not any of the known exception types");
}
Compare the above possibility with this:
try {
/*
* Code, code and more code
*/
} catch(Exception e) {
System.err.println("Something went wrong! Can be exception type 1, 2 or something else");
}
As you can see, differentiating the exception types can help you understand what went wrong in your code.
Related
Though the try-with-resources feature handles all the functionalities for AutoClosable objects itself, but there are some specific cases I have faced in my recent project.
I was reading a file using:
try(InputStream stream = loader.getResourceAsStream("remote-config.xml"))
The issue was that the path from where I am reading the file above was wrong. So, I expected an exception as 'FileNotFoundException'. Now, I know that I can have catch block in place and not have it in place as well when I am using try-with-resources. Also, to my surprise, the catch block I had did not catch any exception and I did not get any error in my logs.
If there is no need of that catch block with try-with-resources, then why can it be added there? And, when it is not there, are there any exceptions thrown? Are the exceptions thrown to the JVM in the second case and how can I log those?
Below is the code I have:
private Map<String, String> fillMappingsMap(Map<String, String> serviceToJndiNameMappings)
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
try(InputStream stream = loader.getResourceAsStream("remoting-config.xml"))
{
if (stream != null)
{
// logic for - read the file , fill the map to be returned.
}
}
catch (IOException | ParserConfigurationException | SAXException e)
{
logger.error("Could not create service to JNDI Name mapping.", e);
}
return serviceToJndiNameMappings;
}
The only exception getResourceAsStream(name) could throw is a NullPointerException and that too, when the name is null. It will not throw any other exception even if the resource is not found.
If you want your code to throw a FileNotFoundException when resource is missing, then use new FileInputStream(String resourceName) (which throws the required file not found exception) to load your resource instead of getResourceAsStream()
The getResourceAsStream throws a NullPointerException only when the resource name is null.
So if you had tried getResourceAsStream(null), then the catch block would catch the NullPointerException(if mentioned in the clause)
If there is no need of that catch block with try-with-resources, then why can it be added there?
If there is no need for training wheels on a bicycle, why can they be added?
Answer: because sometimes there is a need, and sometimes there isn't a need.
In your example, if you need to handle an exception emanating from a try with resources, then you can add a catch to handle it. (And you can even add a finally if you need to.)
(And for what it is worth, you don't have to have a catch on a classic try ... statement. You could just have a finally.)
And, when it is not there, are there any exceptions thrown?
There can be. It depends on what try does.
Are the exceptions thrown to the JVM in the second case ...
Exceptions are not thrown "to the JVM". That doesn't make sense.
But if you are asking if exceptions might be thrown, then yes, they might be. There maybe unchecked exceptions thrown by code in the try block; e.g. code that you indicated by the "// ... fill the map to be returned logic." comment.
For example ... if there was an NPE bug, or if you filled up the heap while filling the map and got an OOME.
... and how can I log those?
I doubt that it is a good idea to log exceptions there. But you could do it by catching them, logging them and then rethrowing them.
Same as if you were logging exceptions normally ...
You seem to be worried by this:
... I am going to miss a very important exception i.e. FileNotFoundException which can make anyone irritated.
You are not going to miss it:
FileNotFoundException is a subclass of IOException so you are definitely catching it when you catch IOException.
Even if you weren't catching IOException, FileNotFoundException is a checked exception. That means that the Java compiler will insist that you either catch it, or declare it in a "throws" clause in the enclosing method.
Finally loader.getResourceAsStream("remote-config.xml") will not throw FileNotFoundException anyway! It is not opening a file. It is acquiring an input stream for a resource. If it can't find the resource, the getResourceAsStream call returns null rather than throwing an exception.
I recommend that you read the Catch or Specify page from the Oracle Java Tutorial. It will answer a lot of your confusion about Java exceptions and exception handling.
Also, read the javadocs for ClassLoader.getResourceAsStream to understand how it behaves if it cannot find a resource.
I am getting fortify issue as :
Poor Error Handling: Throw Inside Finally
I am not throwing exception inside finally block, but still it is showing this error.
Please find the code below.`
catch( IOException | JSONException | URISyntaxException e)
{
if(instream == null) {
throw new IOException("InputStream not valid");
}
return e.getMessage();
}finally {
if(instream != null ) {
instream.close();
}
if(urlConnection != null ) {
urlConnection.disconnect();
}
}
No, you are: inStream.close() can throw.
Generally, 'curing' the warning is actually going to make your code worse. This is the problem:
IF the try block throws an uncaught exception
In this case, the finally block is executed. Let's say that the finally block runs in.close();. Especially if the entire reason we got here is that in got disconnected and started throwing IOEx, this is likely to also throw an IOEx. Any exceptions thrown out of a finally block 'overwrite' the exception that caused us to be here, and the stack trace from that close call is far less useful.
So this is bad.
We can fix it by wrapping the in.close() in your finally block in a try { .. } catch (Exception ignore) {}. But then, the other scenario is really bad:
IF we get here 'normally'
It's possible for an input stream to work perfectly, and then when you close it, it throws. For a good long while common wisdom was 'eh, whatever, who cares, I got my data', but that's not a sensible idea: If an input's close ends up throwing, that probably means you didn't actually get all data yet, otherwise, why did it do that? So, now, silently swallowing any exceptions is a bad idea, and we want to throw it.
Without bending over backwards, using a boolean to track how we got to the finally block and depending on it, swallowing that exception or not, it is not possible to do it right.
Because this is so tricky, try-with-resources actually does it right and generates the requisite boilerplate.
Thus, the REAL solution: If you are closing resources in a finally block, don't. Use the try (ResourceType r = new ResourceType()) { ... } syntax instead.
If you truly can't do that, and you also can't make it work by creating a wrapper that is AutoClosable and will for example do nothing if the resource is null, then you're basically forced to tell your linter to stop complaining about this.
Ok I know catching throwable is not a good idea:
try {
// Some code
} catch(Throwable e) { // Not cool!
// handle the exception
}
But recently I was reading through an open sourced code and I saw this interesting (at least to me) piece of code:
try {
// Some Code
} catch (Throwable ex){
response = handleException(ex, resource);
}
private handleException(Throwable t, String resource) {
if (t instanceof SQLEXception) {
// Some code
} else if (t instanceof IllegalArgumentException) {
//some code
} //so on and so forth
}
This doesn't seem to be that bad? What is wrong with this approach?
There are various reasons why you should not catch a Throwable. First of all is, that Throwable includes Errors - and there's normally not much an application can do if one of these appears. Also Throwable reduces your chances of finding out, WHAT has happened. All you get is "something bad has happened" - which might be a catastrophe or just a nuisance.
The other aproach is better but of course I still would not catch Throwable, but try to catch more specific Exceptions, if possible at all. Otherwise you are catching everything and then try to sort out which kind of bad thing happened. Your example could be written as...
try {
...
} catch (SQLEXception ex){
response = ... ;
} catch (IllegalArgumentException ex){
response = ...;
}
...which would reduce the amount of if ( ... instanceof ... ) blocks (which are only needed because the author first decided to catch everything in one big bucket). It something actually throws Throwable, then you don't have much choice, of course.
You are right when you say that catching Throwable is not a good idea. However, the code that you present in your question is not catching Throwable in an evil way but let's talk about that later. For now, the code that you present in your question has several advantages :
1. Readability
If you look at the code carefully, you will notice that even though the catch block is catching a Throwable, the handleException method is checking the type of exception thrown and possibly taking different actions based on the exception type.
The code presented in your question is synonymous to saying:
try {
doSomething();
} catch (SQLEXception ex){
response = handleException(resource);
} catch(IllegalArgumentException ex) {
response = handleException(resource);
} catch(Throwable ex) {
response = handleException(resource);
}
Even if you have to catch 10+ exceptions only, this code can easily take up a lot of lines of code and the multi-catch construct is not going to make the code any cleaner. The code that you present in your question is simply delegating the catch to another method to make the actual method that does the work more readable.
2. Reusability
The code for the handleRequest method could easily be modified and placed in a utility class and accessed throughout your application to handle both Exceptions and Errors. You could even extract the method into two private methods; One that handles Exception and one that handles Error and have the handleException method that takes a Throwable further delegate the calls to these methods.
3. Maintainibility
If you decide that you want to change the way you log an SQLExceptions in your application, you have to make this change in a single place rather than visiting every method in every class that throws an SQLException.
So is catching Throwable a bad idea?
The code that you present in your question is not really the same as catching Throwable alone. The following piece of code is a big no-no:
try {
doSomething();
} catch(Throwable e) {
//log, rethrow or take some action
}
You should catch Throwable or Exception as far away in the catch chain as possible.
Last but not the least, remember that the code you present in your question is framework's code and there are certain errors that the framework can still recover from. See When to catch java.lang.Error for a better explanation.
Catching Throwables out of laziness is a bad idea.
This was particularly tempting before try-multi-catch was introduced.
try {
...
} catch (SomeException e) {
//do something
} catch (OtherException e) {
//do the same thing
} ...
Repeating catch blocks is tedious and verbose, so some people decided to just catch Exception or Throwable and be done with it. This is what should be avoided because:
It makes it difficult to follow what you're trying to do.
You may end up catching a lot of stuff you can't deal with.
You deserve bonus punishment if you completely swallow the Throwable in the catch block. (And we've all seen code that does that...:))
But catching Throwables when it is absolutely necessary is fine.
When is it necessary? Very rarely. In framework-style code there are various scenarios (dynamically loading an external class is the most obvious one), in a standalone application a typical example is to attempt to display/log some kind of error message before exiting. (Bearing in mind that the attempt may fail, so you don't want to put anything critical there.)
As a rule of thumb, if there's nothing you can do about an exception/error, you shouldn't catch it at all.
You posted a link to Jongo, which demonstrates one possible use for this technique: re-using error handling code.
Let's say you've got a large block of error handling code that naturally repeats itself in various places in your code - for example Jongo produces standard responses for some standard classes of errors. It may be a good idea to extract that error handling code into a method, so you can re-use it from all the places it's needed.
However, that's not to say that there's nothing wrong with Jongo's code.
Catching Throwable (rather than using multicatch) is still suspicious, as you're likely to catch Errors that you're not really in a position to handle (are you sure you meant to catch ThreadDeath?). In this situation, if you absolutely have to catch Throwable, it'd be better to "catch and release" (i.e, rethrow anything that you didn't mean to catch). Jongo doesn't do this.
There are exactly two valid uses for using a huge net:
If you will handle everything uniformly, like a top-level catch for logging/reporting, possibly followed by an immediate exit.
To reduce duplication, by exporting all the handling into its own method.
Catch the most derived common ancestor there is to avoid extra-work and increase clarity.
DRY is an important design principle.
In both cases, unless you expected that exception and handled it completely, rethrow.
First of all, catching Throwable makes your application rather intransparent. You should be as explicit as possible on catching exceptions to enable good traceability in exceptional cases.
Let's have a look at the method handleException(...) and see some of the problems that occur by this approach:
you catch Throwable but you only handle Exceptions, what happens if an e.g. OutOfMemoryError of type Error is thrown? - I see bad things to happen...
Regarding good object oriented programming using instanceof breaks the Open-Closed-Principle and makes code changes (e.g. adding new exceptions) really messy.
From my point of view, catch-blocks are exactly made for the functionality that are tried to cover in handleExceptions(...), so use them.
Java 7 solves a bit of the tedium that is multi-catching of similar exceptions with similar handling. You definitely should not be doing what the person has done here. Just catch the appropriate exceptions as needed, it may look ugly but then that's what throws is for, pass it to the method that should catch it and you shouldn't be wasting too much code space.
Check out this link for more information.
Just to provide balance - there is one place where I will always catch (Throwable):
public static void main(String args[]) {
try {
new Test().test();
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
At least something shows somewhere that something went wrong.
You can always catch different type of exceptions and perform some operations based on the type of the exception you got.
Here is an example
try{
//do something that could throw an exception
}catch (ConnectException e) {
//do something related to connection
} catch (InvalidAttributeValueException e) {
// do anything related to invalid attribute exception
} catch (NullPointerException e) {
// do something if a null if obtained
}
catch (Exception e) {
// any other exception that is not handled can be catch here, handle it here
}
finally{
//perform the final operatin like closing the connections etc.
}
For my Java application, I am creating an instance of a user information object and populating it with a service that I don't control the source for.
The code looks like this:
// username given as parameter
UserInfo ui = new UserInfo();
try {
DirectoryUser du = LDAPService.findUser(username);
if (du!=null) {
ui.setUserInfo(du.getUserInfo());
}
} catch (Exception e) {
// Whatever
}
If LDAPService.findUser() can't locate a user, it will throw a NullPointerException and grind the rest of my application to a stop. It's okay if the user information isn't populated, so I want to be able to continue without causing everything else to start throwing exceptions.
Is there a way to do this?
I've upvoted Amir Afghani's answer, which seems to be the only one as of yet that actually answers the question.
But I would have written it like this instead:
UserInfo ui = new UserInfo();
DirectoryUser du = null;
try {
du = LDAPService.findUser(username);
} catch (NullPointerException npe) {
// It's fine if findUser throws a NPE
}
if (du != null) {
ui.setUserInfo(du.getUserInfo());
}
Of course, it depends on whether or not you want to catch NPEs from the ui.setUserInfo() and du.getUserInfo() calls.
You could catch the NullPointerException explicitly and ignore it - though its generally not recommended. You should not, however, ignore all exceptions as you're currently doing.
UserInfo ui = new UserInfo();
try {
DirectoryUser du = LDAPService.findUser(username);
if (du!=null) {
ui.setUserInfo(du.getUserInfo());
}
} catch (NullPointerException npe) {
// Lulz # your NPE
Logger.log("No user info for " +username+ ", will find some way to cope");
}
You are already doing it in your code. Run this example below. The catch will "handle" the exception, and you can move forward, assuming whatever you caught and handled did not break code down the road which you did not anticipate.
try{
throw new Exception();
}catch (Exception ex){
ex.printStackTrace();
}
System.out.println("Made it!");
However, you should always handle an exception properly. You can get yourself into some pretty messy situations and write difficult to maintain code by "ignoring" exceptions. You should only do this if you are actually handling whatever went wrong with the exception to the point that it really does not affect the rest of the program.
It's generally considered a bad idea to ignore exceptions. Usually, if it's appropriate, you want to either notify the user of the issue (if they would care) or at the very least, log the exception, or print the stack trace to the console.
However, if that's truly not necessary (you're the one making the decision) then no, there's no other way to ignore an exception that forces you to catch it. The only revision, in that case, that I would suggest is explicitly listing the the class of the Exceptions you're ignoring, and some comment as to why you're ignoring them, rather than simply ignoring any exception, as you've done in your example.
You are actually ignoring exception in your code. But I suggest you to reconsider.
Here is a quote from Coding Crimes: Ignoring Exceptions
For a start, the exception should be logged at the very least, not
just written out to the console. Also, in most cases, the exception
should be thrown back to the caller for them to deal with. If it
doesn't need to be thrown back to the caller, then the exception
should be handled. And some comments would be nice too.
The usual excuse for this type of code is "I didn't have time", but
there is a ripple effect when code is left in this state. Chances are
that most of this type of code will never get out in the final
production. Code reviews or static analysis tools should catch this
error pattern. But that's no excuse, all this does is add time to the
maintainance and debugging of the software.
Even if you are ignoring it I suggest you to use specific exception names instead of superclass name. ie., Use NullPointerException instead of Exception in your catch clause.
You can write a try - catch block around the line you want to have ignored.
Like in the example code of yours. If you just continue your code below the closing bracket of the catch block everythings fine.
LDAPService should contain method like LDAPService.isExists(String userName) use it to prevent NPE to be thrown. If is not - this could be a workaround, but use Logging to post some warning..
Printing the STACK trace, logging it or send message to the user, are very bad ways to process the exceptions. Does any one can describe solutions to fix the exception in proper steps then can trying the broken instruction again?
This question already has an answer here:
What does "error: unreported exception <XXX>; must be caught or declared to be thrown" mean and how do I fix it?
(1 answer)
Closed 8 months ago.
While learning Java I stumble upon this error quite often. It goes like this:
Unreported exception java.io.FileNotFound exception; must be caught or declared to be thrown.
java.io.FileNotFound is just an example, I've seen many different ones. In this particular case, code causing the error is:
OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("myfile.pdf")));
Error always disappears and code compiles & runs successfully once I put the statement inside try/catch block. Sometimes it's good enough for me, but sometimes not.
First, examples I'm learning from do not always use try/catch and should work nevertheless, apparently.
Whats more important, sometimes when I put whole code inside try/catch it cannot work at all. E.g. in this particular case I need to out.close(); in finally{ } block; but if the statement above itself is inside the try{ }, finally{} doesnt "see" out and thus cannot close it.
My first idea was to import java.io.FileNotFound; or another relevant exception, but it didnt help.
What you're referring to are checked exceptions, meaning they must be declared or handled. The standard construct for dealing with files in Java looks something like this:
InputStream in = null;
try {
in = new InputStream(...);
// do stuff
} catch (IOException e) {
// do whatever
} finally {
if (in != null) {
try {
in.close();
} catch (Exception e) {
}
}
}
Is it ugly? Sure. Is it verbose? Sure. Java 7 will make it a little better with ARM blocks but until then you're stuck with the above.
You can also let the caller handle exceptions:
public void doStuff() throws IOException {
InputStream in = new InputStream(...);
// do stuff
in.close();
}
although even then the close() should probably be wrapped in a finally block.
But the above function declaration says that this method can throw an IOException. Since that's a checked exception the caller of this function will need to catch it (or declare it so its caller can deal with it and so on).
Java's checked exceptions make programmers address issues like this. (That's a good thing in my opinion, even if sweeping bugs under the carpet is easier.)
You should take some appropriate action if a failure occurs. Typically the handling should be at a different layer from where the exception was thrown.
Resource should be handled correctly, which takes the form:
acquire();
try {
use();
} finally {
release();
}
Never put the acquire() within the try block. Never put anything between the acquire() and try (other than a simple assign). Do not attempt to release multiple resources in a single finally block.
So, we have two different issues. Unfortunately the Java syntax mixes up the two. The correct way to write such code is:
try {
final FileOutputStream rawOut = new FileOutputStream(file);
try {
OutputStream out = new BufferedOutputStream(rawOut);
...
out.flush();
} finally {
rawOut.close();
}
} catch (FileNotFoundException exc) {
...do something not being able to create file...
} catch (IOException exc) {
...handle create file but borked - oops...
}