Page 1 of 2
Don’t raise an exception – EVER!
We live in a world where in the main most things break slowly. You can hear the chair cracking and creaking long before it gives way under you. Most mechanical structures fail with some warning and the ones that only ever fail catastrophically we like to avoid as clearly dangerous.
It isn’t so with software and it isn’t the case with digital hardware. Software in particular tends to fail abruptly and completely. A program saving some data to disk either completes the entire task or it fails completely crashing to the point where it is unstable and has to be reloaded.
Of course this probably means that the user just lost all their work, but they should have been more cautious and saved more often and they should have had backups and … And all this fell over because perhaps one bit failed to save correctly and a parity error occurred. If the user had been given a chance they might have opted to save the file with a parity error rather than face the loss of the entire work.
All or nothing
Software tends to perpetuate the all or nothing approach to failure that it inherits from the digital hardware that runs it.
This all goes much deeper however because the approach is built into the languages that we use to create the applications.
There are two approaches to what should happen when a programmer writes something that could be nonsense. Once group of languages simply throws up its hands (metaphorically) in horror and stops executing the program.
The other, and far less common, approach is to attempt to complete the operation as best as possible and then continue with the rest of the program. This might not make sense in all situations and it might even be dangerous in some other situations.
For example, if the file system is corrupt even at the level of a single bit, then pressing on with an operation could in principle wipe the entire drive. However, just because you can invent horror stories doesn’t mean it isn’t worth considering. Add to the mix a sort of “do no harm” clause and things begin to look more reasonable.
Software should press on with the task unless the possibility of harming the wider system or itself is detected.
What is should not do at all costs is throw an exception, fail to handle the exception and come to a grinding halt as all the brakes are applied – usually bowing out with a “something unexpected has just happened" error message.
Real world unhandled exceptions
Consider for a moment what the world would be like if throwing an unhandled exception was the way everything was dealt with, even the slightest problems. Your cooker might just switch off half way through the roast because it can’t quite get to the temperature you set, or the freezer might give up keeping things frozen because the water dispenser was blocked. You generally expct your car to limp on if it has a minor problem, sufficient at least to get you home if possible. You would be fairly annoyed with a car that switched off the engine with a “Cylinder 3 not firing reliably” exception and then refused to move. Of course with software finding a way into everyday hardware a car failing because of an exception isn't at all unlikely.
So software should try to follow the example set by analog hardware and just keep on working. For the programmer this is most easy to achieve by having the "keep going" attitude built into the language.
A good example of this is PHP which in development mode signals problems to the programmer with warnings that sound so severe that they surely must cause a runtime error if not fixed. The truth of the matter is that they usually don't and you can set the level that an error causes a PHP program to halt programmatically.
Yes, that's correct you can write instructions that say - the next bit is slightly error prone so just ignore anything that goes wrong. The idea is that PHP is creating HTML for consumption by a web browser which also follows the "keep going" pattern of work so if the HTML sent is slightly wrong syntactically the page rendering shouldn't crash.
However, even if you are stuck working with a language that has a built-in tendency to stop on the slightest error you can do something about it. You can quite simply handle all of the exceptions that are raised - without exception - and stick to the rule that you will never write code that raises an exception.
In this way you keep the show on the road and keep the code running through the processor. If you raise an exception you allow the possibility that some other chunk of software will not handle it and so you are creating a chance that the the whole thing will come to a sudden halt.