Programmatically distinguish exceptions - java

The type of an exception is often enough to handle it properly (for example you try to open a file and get a FileNotFoundException). However there are cases where you might catch multiple exception of the same type. For example, an IllegalArgumentException that can be caused by more than one argument. The IllegalArgumentException does not add any additional methods (or public fields) to the Throwable interface (accoding to the online javadoc) which means that the only information that you can rely on are the nested exception (which may or may not exist) and the message (which is for human consumption).
I don't like the idea of extending IllegalArgumentException to add structured information to it, because other people would have to learn the new class. And I don't like the idea of littering projects with very specific exception classes.
Using the message field is also a bad idea because it's not meant for programmatic access.
I think IllegalArgumentException should have included details such as the class function and argument(s) in question. And in general custom exceptions should provide additional detail (other then just their type) for a more fine grained exception handling.
What are considered generally the best practices for designing exception classes, and handling exceptions of the same type?

As a general rule, I think it is ideal to have one class of exception per "type of action a caller might reasonably want to take". Of course, for one's own custom exceptions there could be a boolean or enum field providing some extra disambiguation, rather than creating trivial subclasses.
In your specific case I'm not convinced that trying to handle the exception is a good idea. RuntimeException and its subclasses usually represent coding issues, and the same is true of IllegalArgumentException. If the argument is illegal it shouldn't be passed in in the first place.
If you're in a situation where you're not sure if an argument is valid (maybe it's user input, or maybe you don't know the specific object you're calling the method on) then a better approach would be to have some way of checking the validity of the argument before passing it. Rather than say "do this" and catch the exception, ask "can I do this?" before calling.

Exception classes should be designed so as to provide all that is needed when they are caught. Note that try/catch statements are actually a form of type switch, so in general it is cleaner to create additional exception classes rather than confuse program logic by nesting too many if's within catch clauses.
It has to be said that catch clauses are not very convenient if you want to organize your error handling code in an object oriented fashion, so there are different trade offs to keep in mind.
Note that standard exception classes do have information available on what piece of code caused the exception, even though I would not advise you to base on it your error handling logic.
If the current exception was thrown in a catch clause for a different exception this should be available with the getCause() method, while the getStackTrace() should provide access to the stack of calls that were active when your exception was thrown.
Again I don't advise you to use this information except for debugging purposes.

Its true that the predefined exception classes are very general. But if you want more specific details about the exceptions then you should go for user defined exceptions. you should create your own exception classes with any level of details!
here is the pseudo code:
public class TooManyArguments extends exception{
public String toString(){
return ("..whatever information you want to give for this exception..")'
}
}
and whenever you encounter exceptional situation throw an instance of this class
throw new TooManyArguments();

Related

Should I declare all exceptions thrown from a method in the method signature or just the super class of the exceptions?

When I throw checked exceptions from a method should I just declare the super class of the exceptions in the method signature or all the different types? If I have the following exceptions:
private class SuperException extends Exception {
}
private class SubExceptionOne extends SuperException {
}
private class SubExceptionTwo extends SuperException {
}
Should the method signature be:
void confirmAccount() throws SubExceptionOne, SubExceptionTwo;
or
void confirmAccount() throws SuperException;
In the last method signature, how do I tell other developers what exceptions that could be thrown from the method? If the different sub types need different handling?
The interface should be as stable as possible. So probably Super. Many libraries use the "Super" strategy, because exception specs cause far more annoyance in maintainability than readability or safety they add. Even the IOException is a Super that nearly all Java library code uses instead of declaring more specific exceptions. (But when they do declare more specific exceptions, it's because the contract is that more general IOExceptions won't be thrown. Read on.)
You might list Sub1 and Sub2 if you really do want to say each of those exceptions can be thrown, but don't want to say that any derivative of Super can be thrown. Perhaps Sub1 is NumberCrunchException and your method calls crunchNumbers() and users of your method can be assured that's the only exception-ful thing your method does. In that case the specific strategy is better.
If the different sub types need different handling, then definitely declare the two different exceptions. Never expect the developer using your method to guess that you are actually throwing different types of exceptions.
If you declare two distinct exceptions, and the user knows from the Javadoc that they are actually descendents of the same class, the user may choose to catch them both with a catch (SuperException e) rather than two individual catch clauses. But it depends on the user's choice.
If you don't declare them separately, your IDE is not going to add the appropriate #Throws to your Javadoc comment. And your Javadoc will therefore only indicate that you're throwing SuperException, which will leave the user in the dark. Solving this by just putting it in the text of the comment is not a real solution. If any tool is using reflection to determine what your method throws, it will not see the individual exceptions in the array returned from Method.getExceptionTypes().
If the functionality expected of the different exceptions is more or less the same and it's just a matter of how they will appear in the logs, it may be better to just use the parent exception, with different messages.
The throws clause is there to convey useful information to the calling method about what might go wrong during invocation of this method. That means that how specific you are will depend on how much information you want to convey; and that will be application-dependent.
For instance, declaring throws Exception is almost always a bad idea: the information this conveys is just "something might go wrong", which is too vague to be useful. But whether calling classes are going to need perfectly fine-grained information in the throws clause is something you need to decide by looking at your program. There's no set answer.

Java interface throws Exception best practice [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I'm defining a new interface API... admittedly not something I do all that often. I'd like to define the interface methods to throw an Exception to allow some flexibility for the implementers. They can then choose to throw an Exception, throw a more specific subclass of Exception, or throw nothing at all. I've read a couple of times that while its good to allow implementing classes this flexibility, it's also bad to define the interface method with "throws Exception". Instead, it's recommended to subclass Exception (e.g. MyException) and throw the subclass. The explanations for this practice were lacking in detail, so can someone elaborate on this best practice please? Thanks.
I can appreciate trying to give the implementers some flexibility, but the exception is part of the API, so you should put some thought into what (checked) exception(s) makes sense.
By saying throws Exception, you are not helping the clients of the interface understand what kinds of failures are expected to give them a chance to react to them appropriately. You can consider akin to accepting a method parameter of Object to allow implementers to decide what arguments they can accept. Its good for the implementer, but a nightmare for the clients of the interface.
Better have an idea what exceptions you need to throw later.
There's the so called Liskov substitution principle, which recommends not to throw exceptions in subclasses that would not be thrown by the super class.
Liskov substitution principle aka. design by contract:
http://en.wikipedia.org/wiki/Liskov_substitution_principle
If you are uncertain which Exception need to be thrown, use "throws Exception" (even if it is uncool). Just do not allow unexpected behaviour by implementing classes when they throw exceptions where they weren't planned by you.
The worst case would be a programmer who desperately throws runtime exceptions because of a lack of throws-declarations.
I prefer to throw Java standard subclass of RuntimeException. This gives the flexibility of allowing the Exception to propagate or be caught without having references to your API.
There are many subclasses to choose from http://docs.oracle.com/javase/7/docs/api/java/lang/RuntimeException.html
Often I use IllegalStateException or IllegalArgumentException
Think of checked exceptions as optional return values. The API whose methods return Object is understandably rare, and the same principle should apply for checked exceptions.
The reason for saying that an interface method declaring to throw the base class Exception is bad practice is because it would in fact make throwing an instance of that very base class a legal implementation of the interface, which is what you clearly want to avoid.
This is why you would only use specialized/custom exception types in your signatures.
I wouldn't go as far as saying that an interface should not declare a throwing of any Exception in advance, as someone said in his answer previously, because the interface is in fact not free floating.
You, as the one declaring the interface, invoke or use the methods in a certain way, and you make assertions on how the methods will be used by your side of the code.
It is in fact a contract that you create. And exceptions are a part of that contract. In fact the one using the interface (not the one implementing it) will be done with his work way before an implementation may exist.
in general, throwing an exception means one of the two options:
asking the caller to take an action based on something that happened, usually hoping he has a broader / better understanding of the situation to take a decision
Notify the caller that the action failed beyond repair
focusing on the first type throwing specific exceptions is a good idea and the called can than do:
try {
} catch (ServerIsBusyException ex) {
// wait 10 sec and continue / try another server
} catch (BadUserNameException ex2) {
// try another name
} ....
second type is usually RuntimeException s that means an unexpected situation
see a good explanation in this answer

Proper Design for Java Interfaces with Respect to Exceptions [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm trying to understand how to properly define interfaces in Java with respect to how exceptions are treated in the language (and runtime).
NOTE: Perhaps this question has already been asked and adequately answered, but my search of SO (and other sites) didn't turn up anything that directly addressed the design question and the trade-offs I present. I'll happily delete this question if an analogous one can be found that answers my question. I apologize in advance for the long-winded question, but I wanted to state the problem as clearly as possible. I'm also aware of the controversy around checked exceptions, but since I am not in a position to change the language and must still work within it, I'd like to select the approach(es) that will cause the least pain in the long term.
The recurring problem I encounter is when I try to define my own interfaces I am faced with the choice of how to specify which (if any) exceptions are allowed to the members of the interface. The trouble is that I have no way of knowing which exceptions are meaningful, since I don't know ahead of time what all of the possible implementations for my interface might be. For the sake of an example, suppose we have the following interface:
// purely hypothetical interface meant to illustrate the example...
public interface SegmentPartition {
// option 1
bool hasSegment(Segment s);
// option 2
void addSegment(Segment s) throws Exception;
// option 3
bool tryAddSegment(Segment s) throws TimeoutException, IOException, ParseException, XmlException, SQLException;
// option 4
void optimizeSegments() throws SegmentPartitionException;
}
What exception types should this interface declare upfront? The options I see are:
don't declare any exception, implementations can only throw RuntimeException's
declare each method as throwing Exception
try to anticipate every possible exception type that makes sense for this interface and declare them as the throwable exceptions.
create my own exception type (e.g. SegmentException) and require that it be thrown with an inner exception as needed for additional detail.
There are problem with each of these approaches, and it's not entirely clear what all of the tradeoffs are likely to be, I've mentioned a few for each case. Ideally, I don't want any exceptions to be thrown by the implementation, but that's not always a practical restriction.
For option 1, the trouble is that many of the exception types that may be thrown are not derived from RuntimeException (for instance IOException or TimeoutException). I could, of course, add these specific exceptions to the interface and then allow other RuntimeExceptions to be thrown as well, but what about user-defined exceptions then? This seems like a poor option.
With option 2 we end up with an interface that seems like it could result in any exception whatsoever (which I suppose is true), and provides no guidance to implementors on what should actually be thrown. The interface is no longer self documenting. Worse yet, every call site of this interface must either be declared as throwing Exception or wrap each call to methods of this interface in try{} catch(Exception), or create a block that catches Exception and tries to suss out whether it was thrown by the interface implementation or something else in that block. Yuck. Alternatively, the code that uses this interface could catch the specific exceptions that the implementations might throw, but then it violates the purpose of having an interface to begin with (in that it requires the caller to know the runtime type of the implementation). In practice, this is the option closest to what most other languages I know take with regards to exceptions (C++, C#, Scala, etc).
With option 3 I must specifically anticipate the potential implementations that could be defined for my interface, and declare the exceptions most appropriate for them. So if I anticipate that my interface may be implemented over a remote, unreliable connection I would add TimeoutException, if I anticipate it may be implemented using external storage I would include IOException, and so on. I am almost certainly likely to get it wrong ... which means that I am going to continually churn the interface as new implementation paradigms surface (which, of course, breaks all existing implementations and requires them to declare non-sensical exceptions as being thrown). A further problem with this approach is that results in ugly, repetitive code ... particularly for large interfaces with many methods (yes, sometimes these are needed) which then need to be repeated at each implementation point.
With option 4 I must create my own exception type, together with all of the baggage that accompanies that (serializability, nesting and inner exceptions, coming up with a reasonable hierarchy, etc). What seems to inevitably happen here is that you end up with one exception type for each interface type: InterfaceFoo + InterfaceFooException. Aside from the code bloat this entails, the real problem is that the exception type doesn't mean anything ... it's just a type used to bundle together all of the error conditions for the particular interface. In some cases, perhaps, you can create a few subclasses of the exception type to indicate particular modes of failure, but even that is questionable.
So what is the right thing to do here, in general? I realize there may not be a cut and dry rule, but I'm curious about what experienced Java developers choose do.
Thanks SO.
Having throws Exception (it it's a checked exception) in an interface means you know under what condition such a checked exception should be thrown. That means that interface already has some knowledge of its implementation. Which should not be the case. Therefore I would go against any throws Exception in an interface. If an interface throws a checked Exception I would suggest simplifying it leaving exception logic to the implementation(s).
A possible simple answer is - one should declare those exceptions which can be and typically will be processed during execution - i.e. to propagate, log or quit after an exception. Apart from an being error, I think that an exception is an unconditionally returned result type.
If the interface will be used internally, i.e. in a database, one possible way is to throw those exceptions that you specifically will/are processing.
If it's a public library, i.e. ExecutorService, some deep analysis can be required.
Example - JavaDoc from ExecutorService:
/**
* ...
* #return the result returned by one of the tasks
* #throws InterruptedException if interrupted while waiting
* #throws TimeoutException if the given timeout elapses before
* any task successfully completes
* #throws ExecutionException if no task successfully completes
* #throws RejectedExecutionException if tasks cannot be scheduled
* for execution
*/
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
All these exceptions are domain-specific and one can may decisions based on their general meaning. So you can actually guess what they mean in the context of invokeAny method given only this method's description.
This means that a couple of prototype implementations can be required to understand what your domain is, what are the typical use cases and which typical errors can be thrown. I don't know how Java libraries were designed, in my case I do many refactorings for my prototype implementations and by doing this I understand the domain.
Some more points:
Java's libraries document runtime exception which can be thrown, so it's perfectly fine to have them.
Thus, implementing classes can throw a domain specific runtime exception if you forget one of the cases.
One may document to wrap undeclared exceptions into one of the returned type exceptions, i.e. into ExecutionException - this is how it's done for java.util.concurrent.
In general? In my experience given the complexities of an engineering issue, and given the options available in a given engineering context, the answer of greatest expeditious value is given highest priority.
Elegance is a question of opinion. However it seems most elegant to me to throw an custom SegmentException on add (if that's a possibility), and to try and minimize the possibility of Exception(s) in general.

Correct Java Exception for a malfomed string

I have a method that should only accept strings of a certain format. When the format is invalid, I want to throw an Exception. I'm quite new to Java, so am not sure what the correct type of exception to use here is. I found there is a IllegalFormatException, which based on the name sounds right, though the docs make me rather unsure about this. What is the correct Exception class to use here?
The method in question is the constructor of a PropertyId class, which takes one string argument, which should match '/^p[1-9][0-9]*$/i'. It should behave essentially the same as this equivalent in Python.
I'd prefer using an Exception provided by the standard library, unless there really is none that is appropriate, or it is generally agreed on that in my case a new Exception derivative should be created.
I am with #TwoThe. IllegalArgumentException is the way to go. In fact, I actually don't think there should be much debate. This situation is exactly what IllegalArgumentException was made for.
IllegalFormatException is misleading for sure, but that (and its subclasses) is for a completely different case--when the format string you provide for output is invalid.
Generating your own custom exceptions should only be done with great care. Only when you have a special case where no standard exceptions apply. That isn't true here, and you don't want your clients to have to deal with non-standard stuff unless absolutely necessary.
Remember, with great power comes great responsibility.
This appear reasonable to me, from the Javadoc for IllegalFormatException
Unchecked exception thrown when a format string contains an illegal
syntax or a format specifier that is incompatible with the given
arguments. Only explicit subtypes of this exception which correspond
to specific errors should be instantiated.
As #BasvandenBroek points out, this is appropriate for String which contain format information, rather than checking the format of a String.
However, it may be that it's parent IllegalArgumentException is best. NumberFormatException is close, but not approriate, and it's parent is also IAE.
Note: you can create your own sub-class of IllegalArgumentException
public class StringValidationFailedException extends IllegalArgumentException {
public StringValidationFailedException(String message) {
super(message);
}
}
Try IllegalArgumentException.
There are many exceptions in Java, but it sounds like you may need a custom exception depending on what you mean by format. There are many examples of that on this site. Here are just two links.
How to create a custom exception type in Java?
How to define custom exception class in Java, the easiest way?

rationale behind Java's exception hierarchy

I find Java's exception hierarchy confusing. Throwable is divided into Error and Exception, and RuntimeException inherits from Exception.
Error is an unchecked exception. Why doesn't Error inherit from RuntimeException then?
Exception is a checked exception. RuntimeException is an unchecked exception, yet it inherits from Exception. Doesn't this violate the Liskov-Substitution-Principle?
Wouldn't it make more sense if Throwable were divided into Exception (checked) and RuntimeException (unchecked), and Error would inherit from RuntimeExeption?
I find Java's exception hierarchy confusing. Throwable is divided into Error and Exception, and RuntimeException inherits from Exception.
A Throwable is anything that can be used to unwind the call stack. This should include some VM level fault (flagged by an Error) and something application specific (flagged by an Exception)
Error is an unchecked exception. Why doesn't Error inherit from RuntimeException then?
Simply because Errors are not Exceptions. There wouldn't be any point in actually "catching" an Error. For eg. What would you do after catching an OutOfMemoryError. Errors are meant to flag something seriously happened at the VM level which is not necessarily handle-able by the programmer
Exception is a checked exception. RuntimeException is an unchecked exception, yet it inherits from Exception. Doesn't this violate the Liskov-Substitution-Principle?
Not really. What the implementors were trying to say was that Exceptions MUST always be checked. Your code will be cleaner if all your methods declare what sort of application/library Exceptions they throw. RuntimeExceptions should only be thrown in case of more general / dynamic situations such as a NullPointerException where the developer might not have coded for the case but is a serious bug which is not exactly something mentioned in the application spec.
The design of exception handling in the two most popular object-oriented frameworks (Java and .NET) is predicated upon the notion that the question of whether to handle a particular exception should depend primarily upon its type, and that the types of exceptions one will want to catch are going to have a hierarchical class relationship. I think Java and .NET do things that way because C++ did it that way, and C++ did it that way because of a desire to avoid hard-wiring any non-primitive types hard-coded into the language. In the absence of a hard-coded type to which all exceptions may be cast, it's impossible for a catch statement to know anything about any exception type for which it is not explicitly prepared. If it will only make sense to catch exceptions one can decode, a catch statement will be able to sensibly act upon those types, and only those types, which derive from the one in the statement.
In retrospect, it probably would have been better to have the decisions of what exceptions should be acted upon and/or resolved by particular catch statements be determined by some means other than the class hierarchy. Among other things, a single attempt to invoke a method may fail because of multiple problems; if that happens, every catch which is associated with any of those problems should trigger, but only when all of the problems have been resolved should normal execution resume. Unfortunately, neither Java nor .NET has any mechanism to achieve such behavior.
With regard to the top-level layout of the hierarchy, I think there was an assumption that every kind of exception that might be thrown by a method would either always be expected by the immediate calling code or never expected by any calling code. Exceptions of the latter type were classified under Error or RuntimeException, while those of the former type were placed elsewhere. In practice, the question of whether an exception is expected by a method's caller should be independent of its place in the hierarchy or even the exception type. The fact that a method is declared as throws FooException does not mean that calling code is always going to expect that the exception could occur. It's very common for code to call a method which is declared as throwing an exception but believe that the circumstances surrounding the call are such that in practice that the particular call won't ever throw.. If the exception does occur, it should behave like an unexpected exception, even if an outer execution context is expecting to catch an exception of that type. Unfortunately, the exception handling mechanisms are what they are, and I don't expect any major overhaul.
I think that even better hierarchy is
Throwable
Exception
CheckedException
RuntimeException
Error
This hierarchy separates Exceptions and Errors (as #Paarth said) and makes it possible to catch all checked exceptions only (without runtime exceptions). But it seems that James Gosling thought different...
Error is not a subclass of Exception because it is not meant to catch (Once an error is occurred usually the program is no longer expected to function). So error should have more higher place in hierarchy as I believe.
It should not violate Liskov substitution because RuntimeException can be catched if you want, but only it's not enforced.

Categories

Resources