Report a bugIf you spot a problem with this page, click here to create a Bugzilla issue.
Improve this pageQuickly fork, edit online, and submit a pull request for this page.Requires a signed-in GitHub account. This works well for small changes.If you'd like to make larger changes you may want to consider usinga local clone.
Errors
I came, I coded, I crashed.Julius C'ster

All programs have to deal with errors. Errors are unexpected conditions thatare not part of the normal operation of a program. Examples of common errorsare:
- Out of memory.
- Out of disk space.
- Invalid file name.
- Attempting to write to a read-only file.
- Attempting to read a non-existent file.
- Requesting a system service that is not supported.
The traditional C way of detecting and reporting errors is not traditional,it is ad-hoc and varies from function to function, including:
- Returning a NULL pointer.
- Returning a 0 value.
- Returning a non-zero error code.
- Requiring errno to be checked.
- Requiring that a function be called to check if the previous function failed.
To deal with these possible errors, tedious error handling code must be addedto each function call. If an error happened, code must be written to recoverfrom the error, and the error must be reported to the user in some user friendlyfashion. If an error cannot be handled locally, it must be explicitlypropagated back to its caller.The long list of errno values needs to be converted into appropriatetext to be displayed. Adding all the code to do this can consume a large partof the time spent coding a project - and still, if a new errno value is addedto the runtime system, the old code can not properly display a meaningfulerror message.
Good error handling code tends to clutter up what otherwise would be a neatand clean looking implementation.
Even worse, good error handling code is itself error prone, tends to be theleast tested (and therefore buggy) part of the project, and is frequentlysimply omitted. The end result is likely a "blue screen of death" as theprogram failed to deal with some unanticipated error.
Quick and dirty programs are not worth writing tedious error handling codefor, and so such utilities tend to be like using a table saw with noblade guards.
What's needed is an error handling philosophy and methodology such that:
- It is standardized - consistent usage makes it more useful.
- The result is reasonable even if the programmer fails to check for errors.
- Old code can be reused with new code without having to modify the old code to be compatible with new error types.
- No errors get inadvertently ignored.
- ‘Quick and dirty’ utilities can be written that still correctly handle errors.
- It is easy to make the error handling source code look good.
Let's first make some observations and assumptions about errors:
- Errors are not part of the normal flow of a program. Errors are exceptional, unusual, and unexpected.
- Because errors are unusual, execution of error handling code is not performance critical.
- The normal flow of program logic is performance critical.
- All errors must be dealt with in some way, either by code explicitly written to handle them, or by some system default handling.
- The code that detects an error knows more about the error than the code that must recover from the error.
The solution is to use exception handling to report errors. Allerrors are objects derived from the abstract classError.Errorhas a pure virtual function called toString() which produces astringwith a human readable description of the error.
If code detects an error like "out of memory," then anError is thrownwith a message saying "Out of memory". The function call stack is unwound,looking for a handler for the Error.Finally blocksare executed as thestack is unwound. If an error handler is found, execution resumes there. Ifnot, the default Error handler is run, which displays the message andterminates the program.
How does this meet our criteria?
- It is standardized - consistent usage makes it more useful.
- This is the D way, and is used consistently in the D runtime library and examples.
- The result is reasonable result even if the programmer fails to check for errors.
- If no catch handlers are there for the errors, then the program gracefully exits through the default error handler with an appropriate message.
- Old code can be reused with new code without having to modify the old code to be compatible with new error types.
- Old code can decide to catch all errors, or only specific ones, propagating the rest upwards. In any case, there is no more need to correlate error numbers with messages, the correct message is always supplied.
- No errors get inadvertently ignored.
- Error exceptions get handled one way or another. There is nothing like a NULL pointer return indicating an error, followed by trying to use that NULL pointer.
- 'Quick and dirty' utilities can be written that still correctly handle errors.
- Quick and dirty code need not write any error handling code at all, and don't need to check for errors. The errors will be caught, an appropriate message displayed, and the program gracefully shut down all by default.
- It is easy to make the error handling source code look good.
- The try/catch/finally statements look a lot nicer than endlessif (error) goto errorhandler; statements.
How does this meet our assumptions about errors?
- Errors are not part of the normal flow of a program. Errors are exceptional, unusual, and unexpected.
- D exception handling fits right in with that.
- Because errors are unusual, execution of error handling code is not performance critical.
- Exception handling stack unwinding is a relatively slow process.
- The normal flow of program logic is performance critical.
- Since the normal flow code does not have to check every function call for error returns, it can be realistically faster to use exception handling for the errors.
- All errors must be dealt with in some way, either by code explicitly written to handle them, or by some system default handling.
- If there's no handler for a particular error, it is handled by the runtime library default handler. If an error is ignored, it is because the programmer specifically added code to ignore an error, which presumably means it was intentional.
- The code that detects an error knows more about the error than the code that must recover from the error.
- There is no more need to translate error codes into human readable strings, the correct string is generated by the error detection code, not the error recovery code. This also leads to consistent error messages for the same error between applications.
Using exceptions to handle errors leads to another issue - how to writeexception safe programs.
Here's how.