Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Best practice for try catch blocks to create clean code? [duplicate]

Possible Duplicate:
Best practices for exception management in JAVA or C#

I've read a question earlier today on stackoverflow and it made me think about what is the best practice for handling exceptions.

So, my question is what is the best practice to handle exceptions to produce clean and high quality code.

Here is my code, I think it's quiet straight forward but please let me know if I'm wrong or not clear! I've tried to keep in mind testability and same abstraction level in methods.

Every constructive comment is welcomed. :)

import java.awt.Point;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;

/**
 * <p>This is a dummy code.</p>
 * The aim is present the best practice on exception separation and handling.
 */
public class ExceptionHandlingDemo {
    // System.out is not a good practice. Using logger is good for testing too (can be checked if the expected error messages are produced).
    private Logger logger = LoggerFactory.getLogger(ExceptionHandlingDemo.class);

    // instance of cannot work with List<Point>
    private interface PointList extends List<Point> {}

    /**
     * The method that loads a list of points from a file.
     * @param path - The path and the name of the file to be loaded.
     * Precondition: path cannot be {@code null}. In such case {@link NullPointerException} will be thrown. 
     * Postcondition: if the file don't exist, some IOException occurs or the file doesn't contain the list the returned object is {@code null}.
     * */
    /* (Google throws NullpointerExceptio) since it is not forbidden for the developers to throw it. I know this is arguable but this is out of topic for now. */
    public List<Point> loadPointList(final String path) {
        Preconditions.checkNotNull(path, "The path of the file cannot be null");

        List<Point> pointListToReturn = null;
        ObjectInputStream in = null;

        try {
            in = openObjectInputStream(path);
            pointListToReturn = readPointList(in);
        } catch (final Throwable throwable) {
            handleException(throwable);
        } finally {
            close(in);
        }

        return pointListToReturn;
    }

    /*======== Private helper methods by now ========*/

    private ObjectInputStream openObjectInputStream(final String filename) throws FileNotFoundException, IOException {
        return new ObjectInputStream(new FileInputStream(filename));
    }

    private List<Point> readPointList(final ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
        final Object object = objectInputStream.readObject();

        List<Point> ret = null;

        if (object instanceof PointList) {
            ret = (PointList) object;
        }
        return ret;
    }

    private void handleException(final Throwable throwable) {
        // I don't know the best practice here ...
        logger.error(throwable.toString());
    }

    private void close(final Closeable closeable) { 
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                logger.error("Failed closing: %s", closeable);
            }
        }
    }

    /*======== Getters and setters by now. ========*/

    // ...

    /**
     * @param args
     */
    public static void main(String[] args) {
        ExceptionHandlingDemo test = new ExceptionHandlingDemo();
        test.loadPointList("test-filename.ext");
    }
}

EDITED:

What I want to avoid is writing lot of catch cases after each other...

like image 450
uthomas Avatar asked Apr 12 '11 09:04

uthomas


People also ask

Are try catch blocks good practice?

It is perfectly fine to use two try/catch blocks if the algorithm requires it. I have often used a new try/catch in a catch block to ensure a safe cleanup so a blanket statement is not possible. +1 Agreed.

Is it good practice to throw exception in catch block?

You can use it in a catch clause, but you should never do it! If you use Throwable in a catch clause, it will not only catch all exceptions; it will also catch all errors. Errors are thrown by the JVM to indicate serious problems that are not intended to be handled by an application.

How do you handle multiple catch blocks for a try block?

Yes you can have multiple catch blocks with try statement. You start with catching specific exceptions and then in the last block you may catch base Exception . Only one of the catch block will handle your exception. You can have try block without a catch block.

What is the minimum number of catch blocks required for a try block?

A try block must have at least one catch block to have a finally block.


2 Answers

A few suggestions at first glance:

  1. You shouldn't catch Throwable and instead catch as specific of an exception as possible. The trouble with catching Throwable is that will include Error classes like OutOfMemoryError and the like. You want to let those pass through (they're unchecked for a reason).
  2. When you log exceptions always pass the exception and not just its toString(). It's very hard to diagnose problems without the stack trace.
  3. You probably don't want a general exception handling method.

So at places you catch exceptions you want something like this:

} catch (IOException e) {
    logger.error("some relevant message", e);
    // now handle the exception case
}

The message should include some contextual information if possible. Anything that might help tracking down the problem when someone is hunting through logs.

like image 97
WhiteFang34 Avatar answered Oct 04 '22 02:10

WhiteFang34


For checked exceptions that I'm not going to bother, I always use org.apache.commons.lang.UnhandledException.

For example

/**
 * Calls Thread.sleep(millis)
 */
public static void threadSleep(final long millis) {
    try {
        Thread.sleep(millis);
    } catch (final InterruptedException e) {
        throw new UnhandledException(e);
    }
}
like image 31
artbristol Avatar answered Oct 04 '22 01:10

artbristol