I want to know whether it would be right to use exception classes as regular classes to handle application errors (just regular controlled errors, not exceptional ones), without throwing them with the proper language clause (eg. instantiating them and returning them from a method). I've been discussing this topic recently with some colleges and I think that exceptions should only be used as exceptions, but I'd like to listen to more opinions.
What you mean by "controlled error" is actually known by the name checked exception.
"Exceptional exceptions" are known as unchecked exceptions.
The difference is explained here: Checked vs Unchecked exception
So, you see: Java comes with a built-in mechanism to distinguish between
exceptions caused by programming mistakes (e.g. NullPointerException when passing unexpected null as an argument) -- unchecked exceptions
versus anticipated exceptions that should be handled by the caller (e.g. IOException when some kind of I/O went wrong) -- checked exceptions
Returning instances of Exception (or any subclass) would be considered a misuse in virtually all circumstances.
You could ask your colleague how he/she would implement an exceptional outcome of a method with this signature:
public String createStringOrFailWithException();
Returning an Exception? Certainly not, because this requires a different return type.
Throwing the exception instead allows you to keep the return type, and to benefit from vast exception handling capabilities, including finally blocks and try-with-resources statements, to give only two examples that you don't want (should not) implement by yourself.
I suggest keeping Exceptions "exceptional". I.e. don't build them into your app logic. Use more meaningful things like a ActionXResponse class etc that could indicate failure, and even have an Exception as a property which the controller could check for "controlled exceptions". It's much more meaningful when you have your own class as a response.
Another guideline I'd suggest, along with keeping Exceptions "exceptional" is to avoid checked Exceptions (compile-time).
Related
I am confronting with the following issue for some time.
Let's say you have some code and at some point you need to throw an exception. Let's suppose we want to throw a runtime exception.
Java comes with plenty of exceptions and, in some cases, you may find one suitable for your case.
The problem is how can I figure out which of the exceptions is most suitable for my case?
My question is only about the existent Java implementations of RuntimeException and not custom exception which are extending this class.
Let's take an example. I have the following switch statement:
switch(something){
case A: ... break;
case B: ... break;
default: throw new AJavaRuntimeException("No such case defined");
}
What should I use instead of AJavaRuntimeException and comes with Java? How to find the proper exception through Java?
The easiest solution would be to extend RuntimeException and create NoSuchSwitchCaseDefinedException. Or even throw a RuntimeException. But... Maybe Java already has something for this.
Browsing the API for Direct known subclasses of RuntimeException will probably get you your best fit out of the "catalog".
In this case, you could either throw:
IllegalStateException, signalling an illegal state in your program or
IllegalArgumentException, signalling a bad argument
Etc...
If you can't find your exact match, you shouldn't hesitate to extend Exception or RuntimeException depending on your requirements (checked vs not checked).
If you need to throw an exception independently, better throw a custom user defined exception and it has to be checked one.
Never throw runtime exceptions on your own.
Create business exceptions and throw them.
There are many philosophies to follow here. The philosophy I follow is that unchecked exceptions (i.e. everything inheriting from RuntimeException or Error) are solely used to report programming errors (e.g. though an error dialog or a log message). Programming errors should only be handled in a generic way (e.g. by aborting an operation, skipping an optional processing step, etc.). This means that the actual type used for the exception does not matter in a technical sense.
What does matters is that the exception, its name, its message, its accompanying JavaDoc comment make it as simple as possible to identify what triggered the bug, what a possible workaround might be and how to fix the bug in the end.
If you are writing a library that might fail because of incorrect usage, having domain-specific unchecked exceptions might make working with the library more pleasant because you have the opportunity to provide a lot of context and documentation to an error that might otherwise be obscure.
If you are writing an end-user application or service, you or your time are probably one of the only people ever seeing those exception so that extra work might not be worth it and just throwing RuntimeException with a short description of the problem as its message might be enough.
I have a class XYZ whose public functions throw Exceptions.
I have been advised that all public functions exposed by XYZ should throw exceptions called XYZDataException or XYZSystemException. So even if I get other exceptions within the public methods they need to be wrapped by these XYZExceptions.
I have a couple of questions:
What is the advantage of wrapping exceptions with XYZException?
What is the advantage of differentiating between System and Data exceptions?
To me it feels right to just throw whatever exception occurs without wrapping it further.
A lot of Exception handling depends on how you plan on extending it later on. For example, if developer B came along and wanted to modify some of your code, it would be a lot easier if he understand what Exception meant what in which case. In that case, having specific Exceptions makes more sense.
As to breaking up System and Data exceptions - a Data exception would basically be something that should be non-fatal that occurs because of bad data. A System exception would be because your System failed in some way. Again, this all points to how you want to use it later on. If you want to use your code solely, and you don't care about how your exceptions come back out, then by all means, go with what is easiest at the time.
I have found that when working with other developers on a project, it is a lot easier for them to grasp what is going on when you subclass your Exceptions and throw them in specific cases.
Hope this helps!
Yes, it means they can be explicitly caught by code that knows how to handle them.
for instance, imagine you had:
class MyRecoverableException extends Exception {
...
}
You could then have code that can differentiate between them automatically, and react accordingly, such as:
try{
// ... do something ...
}catch(MyRecoverableException e) {
// Recover
}catch(Throwable t) {
// Log fatal reason, and exit gracefully.
}
Obviously how many you need is a problem to be solved by you, the application developer, but a clean separation can make all the difference when working out what went wrong, and subclassed exceptions can hold additional properties, used to pass pertinent information to handlers about the exceptional circumstances that brought them about.
Having a base type to extend from for your application/library never hurts either - if for no other reason than to allow separation of source when logging - but the exact hierarchy and complexity required beyond that depends entirely on the project. Some designs have natural and obvious choices, some require a bit more forethought (and occasionally a bit of afterthought and refactoring).
As usual, "it depends". As a general rule it does not make sense to blindly create an exception hierarchy on a per-class basis. App-specific exceptions should group exceptions in a way meaningful to that particular app, so there might be a top-level exception, then sub-classed exceptions for things like the data layer, communication layer, utilities, whatever.
The advantage is that higher levels dealing with those exceptions are not exposed to the implementation details that generate those exceptions. Also, perhaps to a lessor degree, exceptions may be grouped more meaningfully (is it relevant that it was an IOException, or is it enough to know there was a problem writing to whatever output store you're using).
Another great advantage is that app-specific information may be captured in the custom exceptions. Things like user IDs, account numbers, etc.--any application state--which must be stored as part of a string message in a "stock" exception may be assigned to a property. This may avoid random parsing issues if you actually do anything with the exceptions or try to trace through a particular event stream.
According to msdn:
To wrap an exception, you specify it as the inner exception of a new exception and then throw the new exception. This practice should be used only in situations where the original exception is not meaningful to the person who receives the exception, or the call stack for the exception is misleading or uninteresting.
Suppose method M1 is documented as throwing an exception of type X when some condition occurs. M1 calls method M2, which happens to throw an exception of type X which M1 is not prepared to handle. If M1 doesn't catch the exception from M2, the caller is unlikely to figure out that the exception thrown out of M1 isn't an X thrown by M1, but is instead an X thrown by M2, and its practical meaning and implications may be very different. Having M1 throw an exception of a type which will never be thrown by M2 may avoid this issue (though there could still be trouble if M2 could call M1 on some other object).
I am following this great discussion at SO, titled: The case against checked exceptions , but I am unable to follow where exactly RuntimeException should be used and how it is different from normal Exceptions and its subclasses. Googling gave me a complex answer, that is, it should be used to deal with programming logic errors and should be thrown when no Exception should normally occur, such as in the default block of switch-case construct.
Can you please explain RuntimeException in greater detail here. Thanks.
I am unable to follow where exactly
RuntimeException should be used
That's probably because you are looking at an argument, i.e. people are disagreeing about exactly this point.
and
how it is different from normal
Exceptions and its subclasses.
Very simple: All subclasses of Exception (except for RuntimeException and its subclasses) are checked i.e. the compiler will reject the code unelss you catch or declare them in the method signature. However, subclasses of RuntimeException are unchecked.
Googling gave me a complex answer,
that is, it should be used to deal
with programming logic errors and
should be thrown when no Exception
should normally occur, such as in the
default block of switch-case
construct.
This is the conventional wisdom, which says that for everything that a program can usefully deal with, you should use checked exceptions because then the compiler will force you to deal with them. Conversely, programs can typically not deal usefully with programmer errors, thus they don't have to be checked. This is how the Java Standard API uses RuntimeException.
The discussion you linked to is sparked by the view of some people (this includes me) who think that checked exceptions lead to bad code and should therefore not be used. Since you can't disable exception checking in the compiler, the only way to do this is to use only RuntimeException and its subclasses.
One observation that IMO supports this view is that the conventional wisdom of "use unchecked exceptions only for programmer error" is in fact mainly a rationalization of backwards-reasoning: there is no code safety reason why the compiler should not force you to deal with programmer errors. However, something like NullPointerException and ArrayIndexOutOfBoundsException can crop up almost anywhere, and if those were checked, nobody would ever want to program in Java. Thus, the language designers had to make a, huh, exception for those, and make them unchecked. To explain this, they came up with the "unchecked exceptions are for programmer errors" story.
Quotes from Effective Java 2nd Edition, Item 58: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
The Java programming language provides three kinds of throwables: checked exceptions, runtime exceptions, and errors. There is some confusion among programmers as to when it is appropriate to use each kind of throwable. While the decision is not always clear-cut, there are some general rules that provide strong guidance.
The cardinal rule in deciding whether to use checked exception or an unchecked one is this:
Use checked exceptions for conditions from which the caller can reasonably be expected to recover. By throwing a checked exception, you force the caller to handle the exception in a catch clause or to propagate it outward. Each checked exception that a method is declared to throw is therefore a potent indication to the API user that associated condition is a possible outcome of invoking the method.
Use runtime exceptions to indicate programming errors. The great majority of runtime exceptions indicate precondition violations. A precondition violation is simply a failure by the client of an API to adhere to the contract specified by the API specification.
Here's an example:
When trying to read a file of arbitrary name, the file may not exists. It's not strictly a programming error when a file does not exist (e.g. perhaps it did before but was then accidentally deleted). Clients may want to recover from this. Thus, FileNotFoundException is a checked exception.
If you give a null string as a filename, then NullPointerException (or perhaps an IllegalArgumentException -- another contentious debate) should be thrown. Client of the API is supposed to provide a valid string value; null isn't. As far as the API is concerned, this is a programmer error, which was easily preventable. Both of these exceptions are runtime exceptions.
Item 59: Avoid unnecessary use of checked exceptions also provides additional guidance:
Checked exceptions are a wonderful feature of the Java programming language. Unlike return codes, they force the programmer to deal with exceptional conditions, greatly enhancing reliability. That said, overuse of checked exceptions can make an API far less pleasant to use. If a method throws one or more checked exceptions, the code that invokes the method must handle the exceptions in one or more catch blocks, or it must declare that it throws the exceptions and let them propagate outward. Either way, it places a nontrivial burden on the programmer.
The burden is justified if:
the exceptional condition cannot be prevented by proper use of the API, and
the programmer using the API can take some useful action once confronted with the exception.
Unless both of these conditions hold, an unchecked exception is more appropriate.
So here's a short summary of the recommendation from Effective Java 2nd Edition:
Preventable exceptions that happen due to API user errors should be unchecked.
Exceptions that can't be handled reasonably should also be unchecked.
Otherwise, the exception should be checked.
See also
Effective Java 2nd Edition
Item 58: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
Item 59: Avoid unnecessary use of checked exceptions
Item 60: Favor the use of standard exceptions
Item 61: Throw exceptions appropriate to the abstraction
Item 62: Document all exceptions thrown by each method
Technical definition
An unchecked exception is defined as RuntimeException and its subclasses, and Error and its subclasses. They do not have to be declared in a method's throws clause.
References
JLS 11.2 Compile-Time Checking of Exceptions
Related questions
In Java, when should I create a checked exception, and when should it be a runtime exception?
When to choose checked and unchecked exceptions
The case against checked exceptions
IllegalArgumentException or NullPointerException for a null parameter?
We all know it is needed.
But WHY is it needed in Java alone, when other similar languages that have exception handling capablities don't require us to write "throws Exception"? Is there anyone who knows what was happening when Java language was designed and why they made it that way? Just curious.
P.S. This may not be a practical or really necessary question - it might not help me in anyway with my ongoing projects. But certain language features kindle my curiosity :D
Edit
Looks like my question was very vague! I think I worded the question wrongly. We need to use the "throws Exception" kind of syntax at some points during programming when dealing with Java code. But something like that is never needed in C# or C++ or even VB.Net and PHP. So why Java alone insists on this?
As other answers here have pointed out, the throws clause is only required for checked exceptions, which is a feature that currently only exists in Java.
The official answer as to why Java has checked exceptions is well documented:
Why did the designers decide to force
a method to specify all uncaught
checked exceptions that can be thrown
within its scope? Any Exception that
can be thrown by a method is part of
the method's public programming
interface. Those who call a method
must know about the exceptions that a
method can throw so that they can
decide what to do about them. These
exceptions are as much a part of that
method's programming interface as its
parameters and return value.
However, this decision is highly controversial, even within the Java community:
Recently, several well-regarded
experts, including Bruce Eckel and Rod
Johnson, have publicly stated that
while they initially agreed completely
with the orthodox position on checked
exceptions, they've concluded that
exclusive use of checked exceptions is
not as good an idea as it appeared at
first, and that checked exceptions
have become a significant source of
problems for many large projects.
Eckel takes a more extreme view,
suggesting that all exceptions should
be unchecked; Johnson's view is more
conservative, but still suggests that
the orthodox preference for checked
exceptions is excessive. (It's worth
noting that the architects of C#, who
almost certainly had plenty of
experience using Java technology,
chose to omit checked exceptions from
the language design, making all
exceptions unchecked exceptions. They
did, however, leave room for an
implementation of checked exceptions
at a later time.)
Personally, I find checked exceptions to be useful only when your API makes a habit of catching all exceptions and re-throwing them as something appropriate to your abstraction layer. For example, an in-memory object cache that happens to use a disk or SQL backend to cache data should never throw IOException or SQLException -- instead, it should throw (and declare) some user-defined exception like CacheFailureException or similar.
Also, you might find Ned Batchelder's article Exceptions in the Rainforest illuminating in regard to this question.
It declares that the method can raise an exception, and allows developers and their tools to ensure that they have considered that possibility.
However, the question is imprecise. The declaration is only required when the exception is a "checked" exception. And then, a more specific type of exception should be declared. Throwing a java.lang.Exception is poor style.
Runtime exceptions, that is, exceptions raised by the runtime when specific bugs are encountered, are not required to be declared. Runtime exceptions should be thrown when the error can be prevented by better programming, and doesn't depend on environmental conditions at runtime.
There are two types of exceptions
Checked Exceptions
UnChecked Exceptions
The throws clause tells which checked Exceptions are thrown by the method so that the caller can handle these in the code or they would have to add the throws clause so that in the end someone will have to handle these exceptions.
Java does not require you to write throws Exception on a function declaration, so it is not "needed" in general. It requires you to declare the exceptions that may be thrown by the function, which might be no exceptions at all, or just runtime exceptions. Indeed, using throws Exception is probably a sign of lazy coding, as it acts as an uninformative catch-all.
edit — well now that you've edited your question, the answer you're looking for (as others have said) is that Java has the concept of "checked" exceptions. It was simply a design decision, to supposedly improve code quality. It probably doesn't really help much in the long run; you can't fix a bad coder with a language trick.
Java is a very organized language which prevents in many situations the unexperient user from missing something relevant or of importance, at least so that errors can be displayed later with a good hint or explanation for what is missing. Forcing you to mention the exceptions on a function/method declaration is a way to keep with that politics and at the same time a way to allow you to define your own specific exceptions and putting them to use.
The point of declaring exceptions in Java was to force the programmer to handle the errors that can arise when executing the program. However, experience showed that in a lot of cases, programmers' "handling" of exceptions did not really handle the exceptions but instead ignored them:
void writeToFile() {
try {
...
} catch (IOException ex) {
// Nothing here
}
}
So in languages more recent than Java the designers preferred not to check exceptions, so that programs without error checking would at least crash with a meaningful stack trace, so you would have a bug easy to debug instead of your program "misteriously" malfunctioning.
Personally I like checked exceptions in Java because:
I do not mishandle exceptions.
Exceptions make me be aware of possible problems that my code could have.
Code is better documented that way.
but I can understand unchecked exceptions. Most of the time I handle an exception is to log it, wrap it with some subclass of RuntimeException and rethrow, because they could only be caused by bugs / misconfiguration / broken deployment. I like to use checked exceptions only for business rule violations.
As I have understood the rationale as put forward by the Java designers, the error situations are generally put in two categories:
Those that are non-fatal and the calling code with good reason should be able to recover from. FileNotFoundException when reading form files, and IOExceptions when working with sockets.
Those that are fatal if they cannot with good reason be expected by the calling code. This includes ArrayIndexOutOfBoundsException and ArithmeticException (when dividing by zero).
Is there any point in having a com.myco.myproj.MyProjRuntimeException,
which completley extends RuntimeException?
Yes. Do throw unchecked exceptions, and subclass them.
There is much talk about whether checked exceptions are really any good. In a nutshell, if I throw a checked exception, does my client really have anything to do with it?
Unchecked exceptions are a good way to notify your clients about exceptional situations (including illegal pre-conditions), and yet not burdening them with the need to wrap calls to your API with try-catch blocks, which most of the time basically serve no purpose, other than debugging, tracing, etc.
So why not throw a RuntimeException? It's not elegant, and it's less readable. Make it your own exception which derives from it, even if it's for no reason other than being more specific when throwing the exception.
It depends on if you want to handle the exceptional condition differently than other exceptions farther up the call stack. If you intend to catch and handle the exception, then I'd recommend creating the custom type. It makes for more legible code and cleaner catch clauses. If you're not going to catch the exception, then there's probably little reason to create a new type.
Not really. The extra information you get from having the exception name show up in a stack trace could be given by simply setting the message string of a standard RuntimeException. However (come to think of it), it might be useful to subclass RuntimeException simply to prepend a custom string onto any message.
I tend to only make custom checked exceptions; generally, the standard unchecked exceptions cover enough potential cases already.
Many people (me and the designers of C# included) believe that checked exceptions are a failed language experiment and avoid them. Then, creating your own exception hierarchy under RuntimeException is an obvious step.
in Effective Java, Joshua Bloch writes:
Use run-time exceptions to indicate
programming errors. The great majority
of run-time exceptions indicate
precondition violations.
That being said, you could use that run-time exception as a base class for a hierarchy of run-time exceptions, used in your project. That way, errors become more legible and traceable.
In my opinion, you should only create new Exceptions if you really need them, i.e. want to catch them and do a specific treatment on them. On all other cases, I don't really see the usefulness.
It's a good style to maintain your own exceptions hierarchy.
But I've seen just a few people who can use this technique with real profit.
Subclass exceptions based on how they are handled rather than who wrote them...
Normally runtime exception can't be handled in another way than logging the error and possibly display an error message.
Checked exceptions might possibly have a specific fallback, and in that case they should probly not subclass a "MyFrameWorkException" - as in that case, catching a MyFrameWorkException would not do more than the generic catch (logging etc.)
It is a rather bad practice to invent a whole hiearachy of exceptions that does have little in common except the fact that they belong to a particular framework.
(packages are supposedly used for just that.)
It is perfectly ok to subclass RuntimeException (if the existing subclasses are not a god fit)
Document unchecked exceptions. Be conservative with checked exceptions, and don't build hierarchies.
Rod Jonhson wrote on this in Expert one-on-one J2EE design and development and as in Tom's answer RuntimeException should be used for programming errors.
A good example is SQLException, lower level data access API should catch them and throw your own "SQLRuntimeException" as most of the time the calling code cannot do anything with the exception. This way, your higher level apis are not forced to catch or carry lower level exceptions in their signature, which make code simpler and more focused on the business domain.