References
I have talked a lot about it. Even though I am not specific about Java the essence holds for it. See in:
Evidently I remember more than I answered but there are cases of others posts very interesting in the same questions or others. It is easy to find on the site.
Importance of the subject
And the subject matter is important because programmers really don’t know how to use it properly. What shows what I say dealing with exceptions is not trivial. I have learned a lot about them by writing these posts. The danger is who thinks he knows everything about the subject and no longer needs to learn anything.
Exceptions are usually defended because, unlike error codes, they require the programmer to treat them. But they do not require proper treatment. So we see so many catch (Exception e)
. The programmer who doesn’t want to do something won’t do it. Capturing a Exception
should be prohibited in the normal flow of a programme (in Main()
or near it, it may be ok to give the last action before the application break).
Capturing very general exceptions hides programming errors. When the programmer tries to capture something that he does not know well why and what can come he ends up capturing what he should not, ends up dealing with something that should not be treated or that should be treated differently. The program should capture the most specialized exception possible that can do something useful.
Taking your example:
If you are working with file access and need to do something when you give whichever problem in trying to manipulate the files, no matter if the file does not exist, if it has reached its end unexpectedly or there is no access permission, there is a single action that must be done, what is the most specialized exception needed? Probably the IOException
. But what if you need to present an error message on the screen when the file does not exist or have to do a specific task when the end of the file is reached unexpectedly? Here the more specialized exceptions need to be captured before and possibly the IOException
then to other IO problems more generally.
Widespread X Specialized Exception
The programmer and only him in the specific case will be able to know if he needs to choose a more specialized or a slightly less specialized exception. There is no cake recipe. Examples may even help but they are often interpreted as cake recipes and misuse perpetuates.
Treat everything as Exception (the superclass of any Exception) and when one comes, give any message to the user and play Stacktrace in a log file
This is no problem if it is done in the right place. Doing this in the core of the program is certainly not right. What you said there is "and then let it break". If the program captures a Exception
has a huge chance to have caught a programming error. There is nothing else to do.
Treat everything as Excpetion, but this time since the program is really very large and the client is probably not looking at the console, print Stacktrace and continue normally.
Programmer looking for problems. Just have something worse, totally swallow the exception.
Warn the user that an error has occurred and give generic treatment.
If it is totally generic falls into the above problem.
Knowing what to solve the problem
But the problem is that in a simple operation so much can happen that it’s really tedious to take care of everything
The basic rule is not to capture an exception that you don’t know or can’t do something really useful, that solves the problem in some way. You can’t do it willingly, much less unwillingly. So you can’t use too generic exceptions to the situation. Programmers get bored because they try to capture too many exceptions, exceptions that should not be captured. Programmers have conditioned themselves to believe that capturing exceptions diminish bugs programs. Indiscriminately they tend to complicate the solution of bugs, they hide the bugs.
much of the possible "errors" are extremely unlikely
Unlikely because? Why shouldn’t they happen in production? If so, don’t treat them. If it’s an unexpected situation, but possible, although unlikely, then you have to deal with it, you have no choice to make a robust program.
What you can do is create utility classes centralizing these treatments. Even so as not to violate the DRY. After a while, you practically don’t need to do new treatments, just use your library. Of course, catches still need to be made in the right places.
If an Ioexception was launched, how to properly treat the error without any specification of what precisely happened?
It is a case of a somewhat more generic capture (only sufficient) and use of more specific information generally (presenting it or logging them, for example). It is not because the program captures a IOException
that the information specific to FileNotFoundException
are not available in the variable used in the capture. It is not a solution for everything, but serves well in some cases. If the action may be the same, but only the message needs to be specific, the capture should be made in this a little more generic.
it’s hard to know what to do
Either you are misinformed or you do not need to do anything with this specific exception.
Java has the debatable advantage of indicating in the API when an exception must be treated. Too bad not all programmers use the resource correctly, then consumers of an API end up suffering to deal with something they shouldn’t. This is another problem. In these cases, the only thing you can’t do is pretend to have nothing to do and simulate an action just to meet the API requirement (the throws
).
When you know what to do with the exception it should usually be captured as close as possible to where it was launched. The treatment should be done very close to the error (of course the treatment may be delegated to utility classes).
Handling specific exceptions can be error as well. Capturing a NullReferenceException
Why? To forcibly create an instance that could not be created before? The error is elsewhere. And there is still the risk of being capturing the same mistake right, but from the wrong place, unexpected. Exceptions can come from anywhere. In the background will be trying to use the exception to do something that should be part of the normal program flow.
Much of what you mentioned is currently solved with GHP (go Horse process) or XGH (Extreme go Horse), very suitable for PHP and Java. Although PHP itself is developed with POG principles, which is different from GHP.
– Bacco
+1 for the POG :D link only
– Jorge B.