- Offensively test for any possible error condition, maybe using assertions. Complain loudly where programmers or maintenance persons can see it, such as a log file.
- Defensively try to handle the error condition after complaining, so that the end user will notice as little as possible/necessary, depending on the situation.
The idea is to expose bugs to programmers, but hide them from the users. The latter may or may not be appropriate, depending on the context: In a public web application, I might want to hide bugs; in a medical application, I might like the user to know about them, rather than rely on questionable data. --FalkBruegmann
With respect, I disagree - not much, but a bit. It's important to separate error conditions arising from environmental factors (for example being unable to open a file, or running out of memory) from programming errors.
The correct response to an environmental factor related error is either to do something else (e.g. look for the configuration file somewhere else, or apply defaults) or to issue a readable and useful error message to the user (if there is one). On the other hand, the correct response to a programming error - the kind of error that OffensiveProgramming
is designed to eliminate - is to explode loudly, with a useful diagnostic of course.
- "If there is one" is an important point. It is unfortunately all too common for software to pause everything until a user interacts with a popup dialog, which is bad if there is background work to be done and the user isn't there, or if the user is there, but the error is repetitive, so that the user has to click hundreds of times to get rid of the popup. I have experienced both problems countless times, and it's almost as bad as an outright crash.
A longer article on this subject is at http://groups.google.com/groups?selm=u1g1j4sh5v.fsf%40noisy.vggas.com&output=gplain
. One upshot of OffensiveProgramming
is that since error checking is streamlined (it's either an assert within the body of the code or an environmental check at the border), the checking for environmental errors is often done more rigorously - since unnecessary checks are not duplicated, developer attention is more focussed on the checks that are actually necessary. -- JamesYoungman
I agree with James: errors caused by environmental factors are supposed to be foreseen by the programmer, who designs the corresponding behaviour of the program; error recovery and management is just another aspect of UseCases
(the program should recover in a specific preferred way) and UserInterfaceDesign
(similar errors should be processed homogeneously).
Programming errors can be regarded as pertinent to a special environmental factor: the Software, which is an actor of UseCases
(sometimes users perceive the software as a set of modules that can fail independently, e.g. a web browser + a web server). Users expect failures and a good design can be helpful in classifying them as harmful, harmless, easily worked around, sporadic etc.
Therefore,the design should account for environmental errors and programming errors: different defensive / offensive strategies should be selected for different needs. For example, the Software is usually important enough that users prefer to lose a fouled elaboration than to lose reliability or damage their data, so crashing the program is a GoodThing
; likewise, producing stack traces, cryptic error codes etc. that users can send to the developers so they can fix the software tends to be the best way to get over software faults. --LorenzoGatti
is along the lines of the ErlangLanguage