Reputation: 709
Many of the built in Java exceptions have no way to accept a "cause"
. Is there any way to assign a cause to these exceptions?
I want to be able to chain exceptions, like with this InterruptedException
example:
try{
//threaded code
}catch (InterruptedException e){
throw new InterruptedException("context-specific information", e);
}
If a constructor like this does not exist, what is the reasoning?
Edit: I've considered throwing either a different exception or runtime exception that accepts a cause parameter. The reason I haven't gone with either of these options is because I'm working within a framework that expects an InterruptedException
, and not some other exception type.
Upvotes: 0
Views: 1515
Reputation: 183456
Is there any way to assign a cause to these exceptions?
Yes; you can use the initCause(Throwable)
method, which allows a cause to be set. It can only be called once for a given exception instance; it's specifically intended for this sort of case.
If a constructor like this does not exist, what is the reasoning?
Oddly enough, even though the great majority of JDK exceptions do support taking causes, the Javadoc for java.lang.Throwable
seems to suggest that that's not the expected default. The Javadoc describes a few reasons that you might want to wrap an exception (neither of which applies in your case: they both have to do with wrapping an exception of one type in an exception of a different type), and it says that the cause-accepting constructors should only be created for "throwable classes that wish to allow causes to be associated with them" or even just for "subclasses that might likely have a cause associated with them" (emphasis mine).
I wonder if it's just that the JDK is behind the times; apparently causes were not originally intended to be used quite as generally as we now expect?
Upvotes: 0
Reputation: 73568
The logical reason for an exception class missing a way to attach a cause, is that they can't have another exception as a cause.
Taking the exceptions given as examples, we've got InterruptedException
and UnsupportedAudioFileException
. Neither of those will have an exception as a cause, since InterruptedException
cannot occur because of other exceptions, but only if a thread is interrupted.
UnsupportedAudioFileException
on the other hand could take a cause, but it would be useless. There's no "deeper" reason for an audio file to not be supported.
Therefore it's no suprise that NullPointerException
doesn't take a cause either. It's not like there are many reasons for that to happen...
If you're using an exception that doesn't take a wrapped exception in the constructor, you're probably using an exception that wasn't designed for that sort of use. While the ready made "general exceptions" like IllegalArgumentException
do take (and even expect) causes to be included, if you can't find an existing one that fits your use case, create your own exception.
If you're working with a framework that expects an InterruptedException
, there are 2 possibilities. Either it was chosen because of the name ("Hey, stopping this job should throw InterruptedException") or it was chosen because of sane design choices. You should first make sure you're not using the framework wrong, since InterruptedException
is not a general use case exception and implies interrupted threads.
Upvotes: 5