Much of what I could answer here can be found in the answer How to best treat exceptions in Java?. There are several links for other answers that if read together gives a good understanding of the problem that exception treatment has become in programming (I know, it is a lot but it is of utmost importance to understand the subject). Although some links not referring to Java the general idea is the same.
The first thing you should ask yourself is what do you gain by capturing the Exception
. Why do you do this? There must be a reason. Is it used to bring better results? Either it’s used because it seems easier, or because a lot of people do it this way?
I imagine you know that an exception should never be "swallowed". In your example this happens but I believe it is just a simplified example. If you didn’t know this, maybe this is the most important new information for you post. Let’s see the example with an action on catch
, so the exception NumberFormatException
is not completely swallowed (although the action performed in the catch does not help much in real case):
try {
Integer i = Integer.parseInt("3")
} catch(Exception e){ //em vez de NumberFormatException
System.out.println("Número inválido");
}
I put in the Github for future reference.
Is the problem solved? The swallowing exception? No! And worse, you’re not even realizing you’re swallowing exceptions. Swallow it by accident. If there is a memory allocation error your application will break saying that there was a Número inválido
. And you’ll wonder why the hell that happened. You swallowed all the other possible exceptions. You captured every possible exception and gave treatment to only one of them.
And if you give the treatment to all of them, you solve it? It may seem so. Is that what you want to do? In a simple problem, do you want to worry about any possible exception? Can you know all of them? They will be stable, meaning there will never be new ones that will make your application less robust? Even if you do, what did you gain from this?
So let’s look at a more likely situation in real application. Let’s look at the situation demonstrated in Lucas Polo’s response. There can occur several exceptions. Trying to treat all as if it were the same thing falls into the same problem.
Let us imagine an even more complicated problem. You call a method, you don’t know what it does (even if you know it doesn’t help much) and it can be modified without you knowing it. It can have many more exceptions. There may be exceptions caused by programming errors that you are capturing and saying that there is only one Número inválido
when the problem is much more serious. There may be errors of Runtime (for real) like resource accesses (files, networks, Dbs) that fail and are definitely not invalid numbers.
If you are lucky (or unlucky) you will use an API that uses checked Exception and know what must treat (by explicitly capturing or delegating). Then you capture the Exception
and "handles" what the API requires. " Treats" all exceptions that are mandatory giving a unique solution that most likely does not solve the real problem.
Even in your simple example it may not seem so complicated to treat all exceptions individually, but then in the future you need to put new operations within the try
and forgets to take care of all possible new exceptions. Virtually anything you do in a program can trigger an exception.
Exception is an extremely complicated flow control. Much more complicated than the goto
that everyone has already understood that it is complicated. She comes from where you can’t imagine (Joel Spolsky’s article about this).
Ground rule
Just treat an exception that you knows specifically what to do with it. If you want to treat a NumberFormatException
, give treatment to the NumberFormatException
. If you’re gonna treat one FileNotFoundException
, take care of it and do not do other things. If you can treat all the exceptions that are IOException
in the same way, ok, this is the most specific and it can be treated. And of course you can deal with the Exception
when it is as specific as possible. This usually only occurs in "high" application methods, the Main()
, for example. In general the only thing to do in this case is to warn the user and register the error (log) for a professional to review.
If you do not know what to do with each of the exceptions you are capturing, do not capture. Capture will only mask what is happening. If you cannot solve the problem let it propagate to a higher level. This is especially true for exceptions caused by programming errors. These errors need to be fixed by the programmer, there is nothing else to do. Capturing exceptions unintentionally hide programming errors.
Why do you wear Exception
?
The impression I have is that it gives a false sense of security to capture all possible problems. But in programming every time you try to solve something you don’t know why, or "just in case," you end up making a mistake. Some just leave the code dirtier, others cause real problems.
To conclude, the final example of Lucas Polo is good until he decides to capture the Exception
right there (note that Oracle does not recommend this). All right, it’s just a fictional example posted here but if it’s used in production you’ll be handling the exception "just in case". It is probably decentralizing and duplicating the same treatment at various points of application. Look in your code to see if there are no duplicates in the treatment.
Of course you may have to do something specific right there for all the exceptions, but this is extremely rare. Usually the treatment of Exception
is only useful in the Main()
or other entry point, in the method that controls an entire framework (UI, for example), or in a thread.
- Don’t swallow exceptions, mostly unintentionally.
- Do not mix unrelated exceptions.
- Do not treat what cannot be treated, even without wanting.
- Use the thought "every time I capture one
Exception
I don’t know what’s happening to my program".
This last one is even valid when using this catch on Main()
. But that’s okay, in this case it’s normal that you don’t know. When catching an exception there is critical to have recorded all the details of the exception, so you may find that you could have captured a more specific exception elsewhere and handled it better. But then you have concrete information that capture is necessary.
Could define "bubbling"?
– ptkato
@Patrick I say that the exception bubbles when it does not stop in that method, but rises to the calling method. Potentially rising to the caller’s caller, and so on, until she is treated or arrives at the top level.
– mgibsonbr
Usually, I have nowhere to let more bubbling. I have k try not to let the program stop, simply. Thanks for the clarification
– Teker