Braving back through my previous post it does feel a tad long-winded but it was a journey I felt I needed in order to get my own perspective and approach to errors.
I’ve settled at the moment on the simplest solution I could; simplicity being my preferred method of work at the moment. Within this simplicity there are defined two error-types, a PRECONDITION and POSTCONDITION. Both of these handle errors by logging them [either to a file or through the std::cerr, whichever fits the current context]. The difference is thus.
A PRECONDITION is designed to inform the Programmer client that he/she [or me] are using the code in the wrong way. A PRECONDITION which fires means that there’s an error in the code which must be corrected before any more work can be on done on expanding the codebase. For this reason when my PRECONDITION fires it uses a [custom] assert that aborts the entire program; it’s yelling at me -> STOP, YOU’VE MADE A MISTAKE IN THE CODE, FIX IT!
Here we see that the assert is a way of handling the error, it’s not really a reporting mechanism [although it informs programmers that something is wrong, it doesn’t report to other code]. In my opinion the PRECONDITION should, ideally, be caught at compile-time [in the same manner that a misuse of the language would cause a compiling error, like trying to assign to an r-value].
A POSTCONDITION error, however, is fired when the function can execute [or should be able to], has executed, worked on some external data [or with another object] but failed to achieve the desired state/result. Here a POSTCONDITION will throw an exception saying “I’ve tried my best but couldn’t do it, now what?”. An exception then is a form of error reporting [very unlike the assert which is error handling], it reports back to other pieces of code meant to deal with the error in whatever way needed [a nice message window, a log file, even a full system shutdown if required]. A POSTCONDITION error, I’ve found, is usually the result of an end-user client using/misusing the software and should be handled by offering options of recovery.
Some examples are probably in order.
PRECONDITION ERROR: The programmer has just violated the internal logic of the program and should fix it immediately.
POSTCONDITION ERROR: File could not be found, do you want to load another file or go back to the main application?
In the POSTCONDITION example the file may be loaded by hand with the programmer working as an End-User, or it might be supplied during the usage of the application by an artist perhaps via a config dialog box or some other mechanism.
So that’s it. This is my system so far, simple and it works for me. Error handling, I think, shouldn’t be a complex issue. It should be robust and easy to use but like any other component of the system, once it becomes too unwieldly to understand it’s just as bad has having no handling at all.
“Things fall apart, the centre cannot hold”