Problem
I wonder what best practices are to indicate implementation errors detected at runtime.
For example, if you write the following method (in Java):
public void doSth(int i) {
try {
runOp(i); // an operation possibly throwing FrameworkException
} catch (FrameworkException e) {
throw new RuntimeException("Implementation error: FrameworkException should never be thrown at this place.", e);
}
}
and you know that by design exception FrameworkException
will never be thrown but as it is a checked exception you have to handle it. Further you want to handle it because it helps debugging if it turns out that the exception can actually be thrown in cases you haven't thought of in the design. Then you want to communicate that this exception is due to an implementation error.
Possible solution
As in the example, throw an unchecked exception (as we don't want to recover) and say it is an "Implementation error" (as we got to a state which is illegal by design).
In Java there doesn't seem to be a standard exception for this, is there in other languages?
The best solution I see is to create a class ImplementationError extends RuntimeException
and throw it in situations where you have detected an illegal state which must be caused by an implementation error.
This is somewhat similar to assertion statements in Java which would terminate the program if a boolean condition is not met. However, assertions cannot be used to state that an Exception should not be thrown (as far as I know) and in addition assertions have to be enabled when running the program which they are not by default.
Going a step further towards language design, it would be nice if statements or blocks could be annotated with something like @IllegalThrow FrameworkException
with which the exception doesn't have to and cannot be catched anymore with a try-catch block. Then ImplementationError
would automatically be thrown when the exception occurs anyway.
The above example would then look as follows
public void doSth(int i) {
@IllegalThrow FrameworkException
runOp(i); // an operation possibly throwing FrameworkException
}
The compiler could simply generate the try-catch block in the first example to implement this feature. Maybe in Java this is even possible with annotation processing?
Questions
- What is best practice to handle these situations? Is the suggested solution appropriate?
- Are there any arguments against the suggested annotation?
Related questions
- How should I handle exception that should never be thrown? is similar but the question is rather about whether or not to check for such illegal states. My point here is more that I do want to throw an appropriate exception (I think it is best practice to give reasons as precise as possible for a crash) and rather ask what kind of Exception should be thrown (class, parameters, ...). Further I want to look at language design, i.e. whether there are better ways to express that you don't expect an exception to be thrown.
- How to deal with checked exceptions that cannot ever be thrown (linked as duplicate of the previous question) again is a bit different because it asks about exceptions that actually cannot be thrown as opposed to exception where you declare their occurrence as illegal by design.
Both questions have interesting and helpful answers but I think this question might have different answers.
class ProgrammingError extends RuntimeException
.assert
is used for that purpose to distinguish programmer errors (accessing an array out of bounds) from external input errors (trying to read from a corrupt file, which is not a fault of the programmer).assert(n >= 0 && n < len); /* this should never happen! */
In C and C++, it has the benefit that it doesn't cost anything in release builds so it doesn't slow down production performance, only debug builds. More importantly, it concisely separates the idea of a programmer error from a real exceptional case.