Here is a short document that describes my view on exceptions management in Java command line applications.
This is a quite different from the case of a library where you should type the exceptions you throw so that receiver will be able to take appropriate decisions.
This is also quite différent for web applications where you won’t catch
exceptions in main()
but in a place where you will be able to return
appropriate status code. You would also probably throw exceptions that would
contain status code to return.
You only catch an exception in these situations:
You never catch an exception if you can’t fix it or if you don’t throw another one. This code is forbidden:
try {
// do something
} catch (Exception e) {
System.out.println("help!");
}
An exception that is not fixed must be propagated to calling code. You can do it by declaring the exception in the method signature. You can also throw a new exception containing raised exception as the cause.
For instance, if an exception is raised reading configuration file, you might write following code:
try {
// load configuration file
} catch (Exception e) {
throw new ManagedException("Error loading configuration file", e);
}
The message of the raised exception will clarify the error and the cause exception (passed to the constructor of the raised exception) will specify the cause of the error (file not found for instance).
You should print a stack trace only for unexpected exceptions. For instance, when configuration file is not found, it is not necessary to print a stack trace, an error message is far better.
In this case, you should throw a managed exception that will carry the error message, is in the example above.
A ManagedException class could look like this:
public class ManagedException
extends RuntimeException {
public ManagedException(String message) {
super(message);
}
public ManagedException(String message, Throwable cause) {
super(message, cause);
}
}
Exceptions that are propagated to calling method must be processed somewhere. There should be only one place in an application where you process these exceptions. This code should look like:
try {
// body of the application
} catch (ManagedException e) {
if (e.getCause() != null) {
LOGGER.error(e.getMessage() + " : " + e.getCause());
} else {
LOGGER.error(e.getMessage());
}
System.exit(1);
} catch (Exception e) {
LOGGER.error("Unexpected error", e);
System.exit(2);
}
Best place for this code is in main() method of the program.
Any feedback welcome (in comments)!
Enjoy!