Should we ignore IOException while close Buffered stream? - java

I load a xml content, and save it to the disk. Then I read it, and try to parse.
When I have successfully parsed xml, should I ignore IOException in 7 line?
catch (IOException ignore) {}
Or some problems may occured?
private HashMap <String, VideoDto> loadContent(String url){
try {
BufferedInputStream bStream = httpGateway.loadContents();
cachedContent = xmlParser.parseVideos(bStream);
try {
bStream.close();
} catch (IOException ignore) {}
return cachedContent;
} catch (XMLStreamException e) {
throw new IllegalStateException("I/O error during integration", e);
}
}
public BufferedInputStream loadContents() {
URL source = config.getContentPath();
URL target= config.getLastImportedFile();
try {
ReadableByteChannel rbc = Channels.newChannel(source.openStream());
FileOutputStream fos = new FileOutputStream(target.getFile());
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Wrong url format", e);
} catch (IOException e) {
throw new IllegalArgumentException("I/O error while saving "+target, e);
}
return createBufferStream(config.getLastImportedFile());
}
private BufferedInputStream createBufferStream(URL url){
try {
return new BufferedInputStream(url.openConnection().getInputStream());
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}

There are three parts to this question:
Q1: Should one ever ignore (squash) an exception?
I think that the answer is ... "it depends".
If the exception cause is known AND it you can catch it precisely (i.e. without also catching exceptions with different causes) AND the correct thing to do is to ignore it then ... IMO ... Yes it is acceptable.
Otherwise. No.
Q2: What does and IOException mean in this case, and does it matter?
The answer is that it is not at all clear. Under normal circumstances, one would not expect an IOException when closing an input stream, and it is hard to know what it might mean. Intuitively it is probably harmless. On the other hand, if you don't know what might cause something it is hard to say whether or not it matters.
Q3: Should you simply ignore this IOException?
I would say no. But I would handle it like this:
} catch (IOException ex) {
// possibly log the exception here.
throw new AssertionError("Unexpected exception", ex);
}
The rationale is that if something totally unexpected does occur, then it would be a good thing if the developer / maintainer could find out, and figure out how to deal with it.
On the other hand, if you could make an a priori assessment that any IOException here is harmless, then simply logging (or even squashing) it might be sufficient.

Never ignore exceptions, even if nothing goes wrong. This is the seed of bugs.
The desired thing to do, if you don't need any actions to be done, is, print its stack trace.
e.printStackTrace();
You may ignore that at any time, but may help you in the long run.

Use the try syntax that exists since Java 7:
try (BufferedInputStream bStream = httpGateway.loadContents();) {
cachedContent = xmlParser.parseVideos(bStream);
}
With this you don't have to call .close() manually.
You should catch all exceptions that are thrown inside the try block, though.

This means that the stream will (probably) still be open, whether that is a problem in your program only you will know. At the very least you should log the exception, otherwise you might get strange results that are hard to detect.
You might also want to look at the try-with-resources syntax which doesn't pose this dilemma:
try (BufferedInputStream bStream = httpGateway.loadContents()) {
cachedContent = xmlParser.parseVideos(bStream);
}

In Effective Java Joshua Bloch gives this as an example of an exception you might want to log and ignore. He says, however, that in general you want to do more than just logging an exception.

Related

Multiple try block

The problem I'm trying to solve is like this: I'm trying to scrape some content from a web page, I'm using selenium, findElementByClassName to get the element content, and it works great until now. But considering that the website that I'm scraping changes one of those element classes in html, I don't want to get an could not find element exception making the rest of the code not execute and jumping straight into the catch block.
My idea was to put each line of code into a try catch block, but having about 15 fields that I want to scrape it makes the code look ugly. See for yourself:
String name = null;
String type = null;
String description = null;
try {
driver.get(link);
try {
name = driver.findElementByClassName(environment.getProperty("booking.propertyName")).getText();
}catch (Exception e){
log.error("error doing thing");
}
try {
type = driver.findElementByClassName(environment.getProperty("booking.propertyType")).getText();
}catch (Exception e){
log.error("error doing thing");
}
try {
description = driver.findElementByClassName(environment.getProperty("booking.propertyDescription")).getText();
}catch (Exception e){
log.error("error doing thing");
}
}catch (Exception e){
log.error("Error during scraping");
}
So if one of these things goes wrong, I still want the rest of the code to continue instead of when having one try-catch block where the first thing failing would stop the other things from executing.
The code above works just fine but it does not look good so my question do you have any ideas of how I could make this better looking.
There is no magic bullet for this. But the standard way avoid repetitive code is to refactor. For example:
try {
type = driver.findElementByClassName(environment.getProperty("something"))
.getText();
} catch (Exception e){
log.error("error doing thing");
}
can be rewritten as:
type = getElementTextIgnoringExceptions(driver, environment, "something");
where getElementTextIgnoringExceptions has been defined as something like this:
public String getElementTextIgnoringExceptions(
Driver driver, Environment env, String name) {
try {
String className = env.getProperty(name);
return driver.findElementByClassName(className).getText();
} catch (Exception ex) {
log.error("error getting " + name, ex);
return null;
}
}
However ... there are some bad things about the code that you are trying to simplify here:
Catching Exception is bad. You have no idea what you will catch, or whether it is safe or sensible to continue.
Not logging the exception is bad. How are you going to diagnose the problem if all you have an "error doing thing" message in your log file?
Continuing after the exceptions is (in the context of your application) liable to cause problems. The rest of your code will be littered with null checks to deal with the elements (or whatever) that couldn't be fetched. Miss one check and you are liable to get an NPE; e.g. in some edge-case that you didn't cover in your unit tests.
These issues are more significant than making the code look good.
If you are using Java 8+, it may be possible to refactor so that the logic is passed as lambda expressions. It depends on the nature of the variables used.

Deserializing a list of objects

I have file that I need to deserialize with multiple objects of the same type.
public static ArrayList<Dog> readDogs() {
ArrayList<Dogs> dogs = null;
ObjectInputStream in = null;
try {
in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(filename)));
dogs = new ArrayList<Dog>();
while(true) {
dogs.add((Dog) in.readObject());
}
} catch (EOFException e) {
} catch (Exception e) {
System.err.println(e.toString());
} finally {
try {
in.close();
} catch (IOException e) {
System.err.println(e.toString());
}
}
return dogs;
}
With the current implementation, I rely upon a try clause to catch and ignore an end of file exception, this seems pretty ugly but I'm not sure how else to handle this?
Don't serialize/deserialize each dog. Serialise/deserialize a single List of Dogs.
All List implementations are themselves Serializable, and serializing them will automatically serialize all its elements.
EOFEception represents an exceptional condition that is caused by something outside of your code. If you are not capturing an Error or a RuntimeException which represents some bug that you could fix in your code, then using an Exception is the best way to deal with the problem.
If the problem is not in your code, which is correct, but outside of it (network down, file not found, file corrupted), it is OK and usually recommended to deal with the problems using exceptions.
There are cases where you should validate data before you use it. If there is a large chance of the data being received in an incorrect format (ex: user input), it might be more efficient to validate it first. But in rare cases where you might have a corrupted file among thousands, it's better to catch the exception when it occurs and deal with it.
You could improve your code logging the exceptions, so you can trace them later. You should also consider which class should be responsible for dealing with the exception (if it should catch it and fix the problem, or if it should declare throws and propagate it to the caller.
Use InputStream.available() to test whether data is available in the stream before reading the next dog.
The following code should work:
try {
FileInputStream fin = new FileInputStream(filename);
in = new ObjectInputStream(new BufferedInputStream(fin));
dogs = new ArrayList<Dog>();
while (fin.available() > 0) {
dogs.add((Dog) in.readObject());
}
} catch (EOFException e) {
Note that you should call available() on the FileInputStream object, not the ObjectInputStream object, which doesn't properly support it. Note also that you should still catch and handle EOFException, since it may still be raised in exceptional situations.

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

Does close()ing InputStream release resoures even if it throws?

Just a simple question. Given this code:
try {
// operation on inputstream "is"
} finally {
try {
is.close();
} catch (IOException ioe) {
//if ioe is thrown, will the handle opened by 'is' be closed?
}
}
If the close() throws, is the file handle still around (and leaked), or will it have been closed?
Not reliably so. If is.close() throws, is might not be marked closed. In any case, there is nothing you can do about it. You don't know the internals of is. The Java 7 equivalent simply hides the problem.
try (InputStream is = Files.newInputStream(...)) {
// Stuff with is.
} catch (IOException is) {
... // Handles exceptions from the try block.
} // No finally. Handled by try-with-reources
If the auto-close throws, the exception is a suppressed exception, and you'll never know if or when the file handle is reclaimed.

Java 1.6 : Learn how to handle exceptions

I did extensive research on exceptions, but I'm still lost.
I'd like to know what is good to do or not.
And I'd also like you to give me your expert opinion on the following example :
public void myprocess(...) {
boolean error = false;
try {
// Step 1
try {
startProcess();
} catch (IOException e) {
log.error("step1", e);
throw new MyProcessException("Step1", e);
}
// Step 2
try {
...
} catch (IOException e) {
log.error("step2", e);
throw new MyProcessException("Step2", e);
} catch (DataAccessException e) {
log.error("step2", e);
throw new MyProcessException("Step2", e);
}
// Step 3
try {
...
} catch (IOException e) {
log.error("step3", e);
throw new MyProcessException("Step3", e);
} catch (ClassNotFoundException e) {
log.error("step3", e);
throw new MyProcessException("Step3", e);
}
// etc.
} catch (MyProcessException mpe) {
error = true;
} finally {
finalizeProcess(error);
if (!error) {
log.info("OK");
} else {
log.info("NOK");
}
}
}
Is it ok to throw a personnal exception (MyProcessException) in each step in order to manage a global try...catch...finally ?
Is it ok to manage each known exception for each step ?
Thank you for your help.
EDIT 1 :
Is it a good practice like this ? log directly in global catch by getting message, and try...catch(Exception) in upper level....
The purpose is to stop if a step fail, and to finalize the process (error or not).
In Controller
public void callProcess() {
try {
myprocess(...);
} catch (Exception e) {
log.error("Unknown error", e);
}
}
In Service
public void myprocess(...) {
boolean error = false;
try {
// Step 1
try {
startProcess();
log.info("ok");
} catch (IOException e) {
throw new MyProcessException("Step1", e);
}
// Step 2
try {
...
} catch (IOException e) {
throw new MyProcessException("Step2", e);
} catch (DataAccessException e) {
throw new MyProcessException("Step2", e);
}
// Step 3
try {
...
} catch (IOException e) {
throw new MyProcessException("Step3", e);
} catch (ClassNotFoundException e) {
throw new MyProcessException("Step3", e);
}
// etc.
} catch (MyProcessException mpe) {
error = true;
log.error(mpe.getMessage(), mpe);
} finally {
finalizeProcess(error);
if (!error) {
log.info("OK");
} else {
log.info("NOK");
}
}
}
Thank you.
Edit 2 :
Is it a real bad practice to catch (Exception e) in lower level and to throws a personnal exception ?
Doesn't exist a generic rule,it depends on your needs.
You can throw a personal exception, and you can manage each known exception.
But pay attention, it is important what you want.
try{
exec1();
exec2(); // if exec1 fails, it is not executed
}catch(){}
try{
exec1();
}catch(){}
try{
exec2(); // if exec1 fails, it is executed
}catch(){}
In your example above it may well be acceptable to throw your own custom exception.
Imagine I have some data access objects (DAO) which come in different flavours (SQL, reading/writing to files etc.). I don't want each DAO to throw exceptions specific to their storage mechansim (SQL-related exceptions etc.). I want them to throw a CouldNotStoreException since that's the level of abstraction that the client is working at. Throwing a SQL-related or a File-related exception would expose the internal workings, and the client isn't particular interested in that. They just want to know if the read/write operation worked.
You can create your custom exception using the originating exception as a cause. That way you don't lose the original info surrounding your problem.
In the above I probably wouldn't handle each exception in each step as you've done. If processing can't continue after an exception I would simply wrap the whole code block in an exception handling block. It improves readability and you don't have to catch an exception and then (later on) check the processing status to see if you can carry on as normal (if you don't do this you're going to generate many exceptions for one original issue and that's not helpful).
I would consider whether multiple catch {} blocks per exception add anything (are you doing something different for each one?). Note that Java 7 allows you to handle multiple exception classes in one catch{} (I realise you're on Java 6 but I note this for completeness).
Finally perhaps you want to think about checked vs unchecked exceptions.
The main point of the exception mechanism is to reduce and group together handling code. You are handling them in the style typical for a language without excptions, like C: every occurrence has a separate handling block.
In most cases the best option is to surround the entire method code with a catch-all:
try {
.... method code ...
}
catch (RuntimeException e) { throw e; }
catch (Exception e) { throw new RuntimeException(e); }
The only times where this is not appropriate is where you want to insert specific handling code, or wrap in a custom exception that will be specifically handled later.
Most exceptions, especially IOExcption in your case, represent nothing else but failure and there will be no handling beyond logging it and returning the application to a safe point, where it can process further requests. If you find yourself repeating the same handling code over and over, it's a signal that you are doing it wrong.
One very important rule: either handle or rethrow; never do both. That is what you are doing in your example: both logging and rethrowing. Most likely the rethrown exception will be caught further up in the call stack and logged again. Reading through the resulting log files is a nightmare, but unfortunately quite a familiar one.
int step = 0;
try
{
step = 1;
...
step = 2;
...
step = 3;
...
}
catch (Exception1 e)
{
log ("Exception1 at step " + step);
throw new MyException1 ("Step: " + step, e);
}
catch (Exception2 e)
{
log ("Exception2 at step " + step);
throw new MyException2 ("Step: " + step, e);
}
...
I'd say it depends on your needs...
If step2 can execute correctly even if step1 failed, you can try/catch step1 separately.
Otherwise, I would group all steps in one try/catch block and made sure that the individual steps produce a log message when they fail.
That way you don't litter your code and still know what went wrong
It's ok to catch each known exception, so you can log what exception occure, and why it did.
Here some links to exception handling patterns/anti-patterns:
Do:
http://www.javaworld.com/jw-07-1998/jw-07-techniques.html
Don't:
http://today.java.net/article/2006/04/04/exception-handling-antipatterns
http://nekulturniy.com/Writings/RebelWithoutAClause/Rebel_without_a_clause.html
About creating your own exceptions, it's certainly useful if you're creating an API, a framework or another piece of reusable code, but in a regular application, it's more debatable and I personally would suggest to stick to existing exceptions.

Categories

Resources