About 10 months ago, I was writing a library. As I was writing it, I started to look at the whole issue of notifying the caller of errors. In typical fashion, I tried to optimize the error handling problem rather than just do the right thing, and just use error codes. I did a ton of research. Here is a current list of links and articles on the subject.
Getting Started
To get you started here are some good starting points. They both received a lot of attention on the internet.
A colorful post by Damien Katz.
A nice opinion piece that is pro-error codes by the famous Joel of Joel on Software.
Read my original post with excellent comments by Daniel Lyons, Paul Clegg, and Neville of the North.
Nutshell
The default and standard way of handling errors since the begining is to just use error codes with some convention of noticing them. For example, you could document the error condition with an api and then set a global variable for the actual code. It is up to the programmer calling the function to notice the error and do the right thing.
This is the technique used by operating systems and most libraries. Historically, these systems have never been consistent or compatable with other conventions. The most evolved system for this would probably be the Microsoft COM system. All functions return an HRESULT, which is essentially an error code.
The next system was the ‘exception-handling’ system. In this system errors cannot be ingored. Exception handlers are declared, optionally, at a given scope. If an exception is thrown (ie an error has occurred), handlers are searched up the stack until a matching handler is found.
IMHO, the exception system isn’t used properly in 90% of the cases. There is a fine balance between a soft error and something exceptional. The syntax also tends to get in the way for even the simplest of errors. I agree that there should be errors that are not ignored, but there has to be a better way.
So, old skoolers are ‘we use error codes, and we like them, dammit – aka, super disciplined programming, usually for real-time, embedded and smaller systems.
The new schoolers are, ‘you have to be kidding about error-codes, use exceptions’ – aks, yeah, we use exceptions, that is what the language gives us… and btw, no, we don’t mind typing on our keyboards a lot
Somehow, there has to be a better way. Maybe it will be system or application, specific.
Moving On – Old / New Ideas
If you don’t mind it being a C++ article, here is an amazing one from Andrei Alexandrescu and Petru Marginean. (Andrei is widely known for his great work on Policy Based design with C++, which is excellent) The artcle is well written and practical. In fact, the idea was so good, the language ‘D’ made it part of the language.
Here is an example:
void User::AddFriend(User& newFriend)
{
friends_.push_back(&newFriend);
try
{
pDB_->AddFriend(GetName(), newFriend.GetName());
}
catch (...)
{
friends_.pop_back();
throw;
}
}
10 lines, and this is for the super-simple example.
void User::AddFriend(User& newFriend)
{
friends_.push_back(&newFriend);
ScopeGuard guard = MakeObjGuard(friends_, &UserCont::pop_back);
pDB_->AddFriend(GetName(), newFriend.GetName());
guard.Dismiss();
}
In D it would look even cleaner:
void User::AddFriend(User& newFriend)
{
friends_.push_back(&newFriend);
scope(failure) friends_.pop_back();
pDB_->AddFriend(GetName(), newFriend.GetName());
}
IMHO, I think exception handling will move more towards systems like this. Higher level, simpler and cleaner.
Other interesting systems are the ones developed for Common Lisp, Erlang, and Smalltalk. I’m sure Haskell has something to say about this as well.
The Common Lisp and Smalltalk ones are similar. Instead of forcing a mechanism like most exception handlers. These systems give the exception ‘catcher’ the choice of retry’ing or doing something different at the point of the exception. Very powerful.
Speaking of smalltalk, here is an excellent article called Subsystem Exception Handling in Smalltalk. I highly recommend it.
My Recomendation
If you are building a library, use error codes. Error codes are much easier to turn into exceptions by the language wrapper that will eventually be built on top.
When programming, don’t get trapped into think about the little picture. A lot of these errors are just pawns in the grand scheme of assuring that you have all of your resources in place before you begin your task at hand. If you present your code in that manner, it will be much easier to understand for all parties.
More Links
Error Codes vs. Exceptions by Damien Katz.
opinion piece that is pro-error codes by the famous Joel of Joel on Software.
Read my original post with excellent comments by Daniel Lyons, Paul Clegg, and Neville of the North.
D Language – Exception Safe Programming
Subsystem Exception Handling in Smalltalk – nice section on history as well
http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
A nice long thread on comp.lang.c++.moderated
Slightly Wacky, But Neat – Exception Handling in C
Half Bakery – Exception Handling in C with Macros
GEF – A C Exception and Design By Contract framework
Exception Handling in C for Embedded Systems – setjmp/longjmp