To take this idea sideways a bit: maybe in another domain it is clearer
What do you do if the car in front of you stops suddenly.
Stop!
So we handle the exception.
So back to code:
What do you do if the file you need is not available ?
either
- Have a backup. Compiled in as a
resource because it's part of your
program. I'm not kidding.
- IFF It's a user supplied file :Tell the user; it's their file.
- Abort the program with a message to the user because your software SYSTEM is
broken.
It is my opinion that there is no fourth option.
Our C#/VC++ brethren choose unchecked exceptions. Many "experts" think checked exceptions are bad: my contention is that life is difficult, get over it.
Checked exceptions represent known failure modes: and have to be addressed.
Your fishbone diagram has a straight lie for normal operation and branches off the side for failures. Checked exceptions are the anticipated failures.
Now, once you start handling Runtime exceptions, then it gets interesting.
A Java program can run mostly normally with functions that do not work.
By this, I mean they throw null pointer exceptions, array bounds errors, invalid arguments, and run out of heap space. This makes incremental delivery quite feasible.
(If you ever do catch Runtime errors, log them. Otherwise you never know to fix things)