I have a class that contains a cache (Set), and the cache is built on instantiation. I'm confused which exception/error should I throw if building cache fail (cannot connect to database or some).
class Provider {
public Provider() {
buildCache();
}
private void buildCache() {
try {
this.cache = getDataFromDb();
} catch (Exception ex) {
throw new ???
}
}
}
One exception comes in my mind is ExceptionInInitializerError, but javadoc says it is thrown on initialize static members.
Should I throw an IllegalStateException cause the cache isn't built so this class is useless?
Clearly I can create my own ErrorOnBuildingCache and throw it but I wonder if any exception in Java library suits this circumstance.
If you're in doubt as to which exception should be thrown, then so will users of your code. So define your own exception type (e.g. FailedToInitializeCacheException) and throw that. No ambiguity that way.
IllegalStateException would be a reasonable fallback position, but you should never, ever use ExceptionInInitializerError (or anything ending in Error) - that's low-level classloader stuff, don't mess with that.
Clearly I can create my own
ErrorOnBuildingCache and throw it but
I wonder if any exception in Java
library suits this circumstance.
This is exactly what you should do. Do not try to use an existing exception, but instead make one of your own. So you know when it is throwed that it is related to your cache and not a static field instanciation error or something.
On a side note, you shouldn't catch exception excepted in very specific cases. Catching exception will catch everything like null pointer exceptions, divide by zero, IO errors, security exception.
What I would do is:
Include the cause when rethrowing the
exception to allow better
investigation
Catch exceptions that could occurs
due to IO/Network problems but
associate them with the right error
message. In you case this is DB exceptions.
Do not catch exception that are due
to programming bugs (like null
pointers), let them popup so you
directly know the real error cause.
Related
I'm implementing the Accumulo BatchWriter interface to perform some additional computation over records before inserting. That computation may throw a checked exception if something goes wrong, but the only exception thrown by BatchWriter is the MutationsRejectedException. As such, I'm unable to throw the necessary checked exception when an error occurs in the pre-processing I'm trying to do.
Now, I could catch the checked exception and simply throw another exception in its place: either an unchecked exception like some RuntimeException or a MutationsRejectedException. Neither option seems great - an unchecked exception is a poor simulacrum of the exception I'd like to actually throw while throwing a MutationsRejectedException wouldn't allow me to see the actual cause of the error.
What is the best practice here?
"MutationsRejectedException wouldn't allow me to see the actual cause of the error."
Yes MutationsRejectedException would allow you to see the actual cause via chained exceptions.
Note the "Throwable cause" in the constructor.
Code for version 1.7;
try{
//...
} catch (Exception e) {
throw new MutationsRejectedException(null, null, (Map<TabletId,Set<SecurityErrorCode>>)null, null, 1, e);
}
.
try{
//...
} catch (MutationsRejectedException e) {
Throwable c = e.getCause();
if(c instanceof MyException){
//...
}else{
throw e;
}
}
The BatchWriter interface actually covers exactly your situation by expecting you to wrap whatever root cause you got into its MutationsRejectedException. That is much better design than declaring a general Exception and exception translation has been the recommended Java idiom since version 1.3 or so.
With throws Exception hopefully crossed out as an antipattern, all the choice you have is between exception translation and the "sneaky throw" idiom. I believe your preference would be the former, especially considering that the latter is very similar to having throws Exception, but more obscure.
I use java.lang.ExceptionInInitializerError to rethrow caught exceptions in static initialisation blocks. I noticed it is not possible to construct with both a message and a cause; only one or the other.
Is there a good reason why?
What alternatives can you suggest for rethrowing checked exceptions as unchecked exceptions from a static init block? Ex: Rethrow as java.lang.RuntimeException which allows both message and cause.
UPDATE: Clarified #2 and added sample code.
public class Sample {
private static final String _FILE_PATH = "blah/blah/blah";
static {
try {
FileReader in = new FileReader(new File(_FILE_PATH));
}
catch (FileNotFoundException e) {
// Option A: Without context message
throw new ExceptionInInitializerError(e);
// Option B: With context message
String msg = String.format("Failed to open file for reading: '%s'", _FILE_PATH);
throw new RuntimeException(msg, e);
}
}
}
Ref: Why doesn't Java allow to throw a checked exception from static initialization block?
As documented here, there is a constructor ExceptionInInitializerError(Throwable thrown), which you probably should be using instead: it conforms to standard exception chaining, which preserves the stack trace and does other useful stuff (see a sample chained-exception output).
Edit
As noted in this answer to the question you linked to: it is forbidden to allow a checked exception to fall out of a static block; unchecked exceptions are fine, but cannot be caught anywhere, unless one is doing manual dynamic class-loading with Class.forName (very uncommon).
This translates to "good luck catching anything you throw in a static initializer". Basically, whatever exception you construct and throw, it won't be much use.
You want to throw an exception with both a message (that you write) and the exception itself. I like to do the same, providing context for the error and the exception. I would throw an Exception (or an instance of an Exception class that extends Exception or a sub class), not RuntimeException since you probably want the exception to be checked. Right?
Generally speaking you should throw checked excpetions in cases where your system could potentially recover (at a higher level) from an exception and runtime exceptions (unchecked) when the system cannot. (James Gosling's view)
It's an Error. Generally errors are what an application shouldn't even try to catch and recover from.
As for why it doesn't have a constructor with both the message and cause, it's probably because the developers of that class didn't deem it necessary since the main purpose of that class is to let you know "oops shit happened bro, can't recover..."
Personally I think that one of those is enough to identify the error.
In the past I'd read tons of code with methods like:
public Object doSomething() throws Throwable {
...
}
Is it common practice to do that?
What are pros & cons?
throws Trowable seemed to me like the "Agent Orange" way of getting the Exception- matter done
EDIT
Handle expected Exceptions in the Method
Throw unexpected Exceptions (one by one)
Don't care of Errors
Is that the way to go?
You should not throw Throwable. Here's why.
Throwable is the top of the hierarchy of things that can be thrown and is made up of Exceptions and Errors. Since Errors by definition arise from unsalvagable conditions, it is pointless to include them in your method declaration. That leaves just Exception.
You should declare your method with throws Exception instead.
Note that the narrower the range of throws the better.
Declaring your method to be throws Exception is ok if your method doesn't generate the exceptions, but instead calls other code that is declared as throws Exception and you want exceptions to percolate up the call stack.
If your method is the generating the exception, then declare a narrower range, eg throws IOException, MyProcessingException, etc
That's a loaded question. This isn't so much about exception handling as it is about code readability.
It depends where you get your code samples from. Professionals prefer to be more specific when throwing out of a method. The main reason is that it keeps your APIs more readable. For example, if your method throws Throwable, that basically means anything could happen and your method doesn't want to deal with it, no matter what. But really, only a limited number of things could happen:
Whatever checked exceptions resulting from other calls you are making in your method
Whatever checked exceptions you are throwing on purpose based on your own assertions
Whatever unchecked exception you didn't plan for
Errors (java.lang.Error) that are more global to the JVM and the environment
By specifically stating the exceptions you want to throw, you are telling the users of your API about what they should beware of. For example, when you use InputStream, you'll notice most methods throw at least java.io.IOException, which gives you some useful information about what you should watch for.
When coding, as a general rule, you want to try to keep your APIs as expressive as possible. You've got essentially one line of code to show the public API of a method (i.e. its signature, annotations too I guess), so you want it completely expressive (return type, name, parameters, but also the thrown exceptions).
As far as catching the throwables and printing the stack trace, I'd say that you should not catch the exception unless you can do something about it. Instead, let it roll up the call stack until some class catches it to do something about it. Sometimes, it may roll all the way up to your main class, which I guess would have to catch it and print the stack trace as last resort. Basically, if you can't act upon the exception, then let it go up the call stack. Also it is extremely rare that you find yourself in a situation where you should silence an exception (i.e. catch it but do nothing about it). That's usually inviting problems when comes time to troubleshoot issues.
Here is a fun but interesting article around misuse of exception handling in general.
In some rare cases it is acceptable to throw Throwables. For example, #Around advices in Spring AOP are usually declared to throw a Throwable.
The following example is copied verbatim from Spring AOP docs:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
#Aspect
public class AroundExample {
#Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
Why is doBasicProfiling declared to throw a Throwable? Because the original method (i.e. the execution join point), might throw an Error, RuntimeException, or a checked exception. So it only makes sense to declare doBasicProfiling to throw a Throwable.
Functionally, it is equivalent with throws Exception, since errors are unchecked.
I see no reason to declare a method to throw Throwable. However, this doesn't mean that catch and printStackTrace is a good alternative.
Usually, you want to catch throwables where you can do something sensible with them.
Code that throws a throwable you don't expect should explode gloriously, so you can see the error and fix the bug.
Is it common practice to do that?
In the JDK it is rare. This is mostly used when it is not clear how to handle checked exceptions.
What are pros & cons?
The pros is that you get your code to compile without worrying about checked exception.s
The cons is that exception you should be handling are being ignored.
Isn't it better to catch and printStackTrace()?
Unhandled exception are usually printed anyway so catching them doesn't help much.
You should catch an exception when you can add some value by doing so and add the exception to the throws clause when you can't.
It is really debatable matter.
Having method throwing too many exceptions will result in lot of error handling code. Some times it is not intended.
But because I don't like too many exception in signature does not mean that Lets use Parent of all exceptions and we are done!! It will not work.
What one can do is categorise exceptions such as BusinessException,ServiceException so that if you have a business rule which says that minimum balance in account can not be less than say 100$ then InsufficientBalance exception will be generated which will be child of BusinessException
so you method will be like
public Object doSomething() throws BusinessException {
if(!hasMinimumbalance())
{
throw new InsufficientBalance(ErrorCode);
}
}
What this will do is club related exceptions together and whenever API user wants to detect exception specific error then he can do it, else generic error handling is possible.
The core point here is on the UI you should display to the user that You have run out of balance and you can not withdraw money
You can say on the larger aspect to display human readable form of error it is really necessary to have separation of exceptions.
Are you asking about Throwable specifically? If so, then it's not good practice. It doesn't provide any useful information to class (method) user.
Throwing (and catching) Throwable (or Exception) is generally bad practice because it 'blankets' any specific exceptions you might want to catch. Then you would have to resort to ugliness like below:
public void myMethod() throws Throwable {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(Throwable t) {
if (t instanceof MyException1) {
// handle exception 1
}
else if (t instanceof MyException2) {
// handle exception 2
}
else {
// handle other exceptions
}
}
}
Which is error prone (and flagged by CheckStyle as a code violation). It is much preferrable to have code like this:
public void myMethod() throws MyException1, MyException2 {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(MyException1 e) {
// handle exception 1
}
catch(MyException2 e) {
// handle exception 2
}
}
Handling an exception just by calling printStackTrace() is usually not a good idea. printStackTrace() sends the stacktrace to standard error, which may not be read at all. A better option is to use the application's logging facility (like log4j) to report the exception. Even then, just logging it might no be enough.
My rule of thumb is:
If you can handle an exception locally, do so. For example when parsing a String as an Integer you could catch the NumberFormatException and return a default value:
prvate int parseAmount(String amountValue) {
int amount;
try {
amount = Integer.parseInt(amountValue);
}
catch(NumberFormatException e) {
// default amount
amount = 0;
}
return amount;
}
If you cannot handle an exception locally, consider if you should expose the exception type that is being thrown. If this type is some obscure (implementation-dependent) type, then wrapping it in your own generic exception type is probably a good idea:
private Customer getCustomer(int customerId) throws ServiceException {
try {
return customerService.getCustomer(customerId);
}
catch(CustomerServiceSpaghettiTangledException e) {
throw new ServiceException("Error calling the customer service", e);
}
}
Here 'ServiceException' is a subclass of Exception created by you. Spring also offers an exception hierarchy specifically for this purpose.
By wrapping the exception you hide the implementation details, making your service layer much simpler to use.
If you decide to throw an exception from your method, you will need to handle it 'higher up' in the callstack. This can be a generic error page in your web application stating that something went wrong and possibly providing an error message or code. In some cases the higher level code can attempt a retry or possibly an alternative way to obtain the required result.
The only use case I can think of would be for test code like unit tests. But Adam's counterpoint still stands "If so, then it's not good practice. It doesn't provide any useful information to class (method) user."
Like such Java code snippet:
public void func() throws XXXException { // throw exception to outer body ------ (2)
try {
......
} catch(XXXException ex) {
// handle exception ------ (1)
}
}
In this condition, how you decide to choose (1) or (2)? Is there any principles in Java exception handling?
If the code that calls the method that throws the exception can properly deal with the exception then it should catch it. If it cannot deal with the exception then it should throw it up.
For instance, if "func" is low-level networking code it should probably throws the exception rather than catch it. The code that ultimatly catches it should display an error message to the user (or whatever else makes sense). If instead "func" is part of the GUI layer it probably would catch the exception and display an error message to the user (or whatever else makes sense).
If you can handle it you handle it. For example, if you are loading a properties file and you get a FileNotFoundException perhaps you can use some default properties. In this case you handle the exception.
If you can't handle it but you think someone else might be able to down the road then you should throw the exception. For example, perhaps you are writing a general utility for reading in property files. In this case you might rethrow the exception so that whoever is using your general utility can then go ahead and load defaults.
If you can't handle it and you don't want to introduce the complexity of throwing the exception then you should send the exception to an exception handling service that you can configure at runtime. This way when unit testing the exception handling service can take that exception and rethrow it as a runtime exception which will crash the test immediately. However, in production code the exception handling service might just log the exception and try and restart the program somehow.
You choose (1) if you want to do something about the exception (e.g. log it, extract info from it). It's also common to throw the exception in the catch block after you are done with it (i.e. throw ex;)
You choose (2) if you want the users of your method to handle it (e.g. Java's String.matches method)
In a nut shell, choose to throw exception to outer body, unless you have a specific reason to catch the exception.
There's an excellent article at the O'Reilly java site about this topic. It goes into some detail about when you should catch versus throw, as well as other stuff, like checked versus unchecked exceptions.
Exceptions represent error conditions. When an error condition occurs, some method in the call chain knows how to handle that error in the context of the application i.e. what to do - ignore, retry, abort, etc. If this is that method that knows how to handle this exception, then you handle it here. If not, you throw it so that the method one level up the call chain receives it and acts on it.
Sometimes, you may want to do both (1) and (2). You may handle the exception, do some intermediate processing and then rethrow it.
public void func() throws XXXException {
try {
......
} catch(XXXException ex) {
logger.log(ex);
throw ex;
}
}
Or you may catch one exception and throw another, for example when you want to wrap a third party exception into an application exception.
public void func() throws YYYException {
try {
......
} catch(XXXException ex) {
throw new YYYException(ex);
}
}
In both cases, this is not the method that fully handles the exception and only does some processing along the way as the exception percolates to the top.
I was not able to find any advice on catch blocks in Java that involve some cleanup operations which themselves could throw exceptions.
The classic example is that of stream.close() which we usually call in the finally clause and if that throws an exception, we either ignore it by calling it in a try-catch block or declare it to be rethrown.
But in general, how do I handle cases like:
public void doIt() throws ApiException { //ApiException is my "higher level" exception
try {
doLower();
} catch(Exception le) {
doCleanup(); //this throws exception too which I can't communicate to caller
throw new ApiException(le);
}
}
I could do:
catch(Exception le) {
try {
doCleanup();
} catch(Exception le1) {
//ignore?
//log?
}
throw new ApiException(le); //I must throw le
}
But that means I will have to do some log analysis to understand why cleanup failed.
If I did:
catch(Exception le) {
try {
doCleanup();
} catch(Exception le1) {
throw new ApiException(le1);
}
It results in losing the le that got me here in the catch block in the fist place.
What are some of the idioms people use here?
Declare the lower level exceptions in throws clause?
Ignore the exceptions during cleanup operation?
First, decide if you actually need to throw from the finally block - think carefully on that - in the case of a failed close() call... well, logging it is fine - but what can a higher layer of your API really do about the problem? So for 99% of the cases, you will log the secondary then re-throw the primary.
Next, if you do need to throw the secondary, decide if the various causes of the secondary exception are important. It will be rare that they are. So set the cause of the secondary to be the primary (either using an appropriate constructor, or initCause() ).
Finally, if you've must throw the secondary, and retain the full stack trace of the secondary and the primary - then you are in to creating a custom Exception to handle the situation. It's ugly, because you will probably want to derive from different parent classes. If this does arise, I suggest creating a helper class that is capable of filling the stack trace of a target exception in such a way that it produces a meaningful trace based on both exceptions (Be sure to use indentation for the secondary so nested exceptions are easy to pull apart).
But mostly, I suggest that you use the log-and-rethrow-primary paradigm. Focus on fixing the primary, and the secondary issues generally take care of themselves (the classic example here is an IO exception that munges things up so badly that the call to close() can't succeed either).
Use a finally block. If you are worried about swallowing the stack trace do the following:
Exception ex = new Exception(le.stackTrace());