Exceptional Ruby is a new ebook by Avdi Grimm exploring exceptions in Ruby. My standing on one foot review: Buy this book if you are at all curious about exceptions in general and Ruby’s exception handling in particular. Error handling in software is a difficult but fascinating subject, and creating correct, robust error handling code is really, really hard. Exceptional Ruby will help you better understand exceptions, and how Ruby’s implementation of exceptions work.
The book has careful definitions of key terms and takes the view that software failure is a breach of contract. A software element fails when its preconditions are met, but the element does not fulfil its promised postconditions or fails to maintain element invariants. An exception signals failure. Avdi outlines the mechanics of Ruby exceptions, walking us through the syntax and semantics of Ruby’s exception handling mechanisms, including some lesser known areas such as retry and raising exceptions during exception handling. The code examples here are short but illustrate the principles clearly.
Next, he considers how to handle the error once the exception occurs. If the error is temporary, retrying the operation may fix the failure. If that isn’t possible, returning a benign value and perhaps logging the error may be the best one can do. But be careful, poorly tested error handling and logging code can introuce their own errors. The most unclear part of the book is the brief discussion of bulkheads, the software analogy to the physical bulkheads on ships which isolate failure consequences to a specific area. I’m not really sure how to construct one in software. The example given is just a general exception handling routine to make sure no exception is passed along.
Exceptions in many ways resemble gotos (more on that in a minute) and can easily be misued, so Avdi discusses alternatives to exceptions. He gives guidance on when exceptions should and should not be used, along with questions to ask and guarantees to give when using exceptions. He defines exception safety testing and how it ensures well defined semantics. He stresses that library clients shouldn’t be surprised by exception handling, and explores how libraries might deal with exception handling.
All that’s left is to wish you luck, provide some external references, and include a couple of appendicies containing proof-of-concept code for an exception tester and a tour of Ruby’s out-of-the-box exception handling. The book is short but information dense, and I recommend Exceptional Ruby even if you are not a Rubyist.
If software were a 10-year-old’s bedroom, failure handling would be the tangled mass of toys and clothes crammed hastily into the closet before Mom comes to inspect.
So says Avdi in the Introduction, and it is very true. The consequences are prefectly expressed in Weinberg’s Second Law: if builders built buildings the way programmers write programs, the first woodpecker that came along would destroy civilization. Writing error handling code, and I mean readable, correct, robust error handling code, is a terribly difficult problem. Exceptions, because they interrupt the sequential flow of the program, acting like the mythical come-from statement, place a huge burden on the developer to Get It Right. Avdi tweeted a pointer to Joel Spolsky’s Making Wrong Code Look Wrong for the other side of the exceptions–Joel doesn’t like exceptions, and explains why after a very interesting discussion of the difference between Apps Hungarian and System Hungarian notation. Read Joel’s post! You’ll learn something. Joel points off to Raymond Chen’s discussion of exceptions (he thinks he isn’t smart enough to use them, and if Raymond Chen isn’t smart enough…) which I definitely encourage you to read as well. Raymond’s advice is sound: When you’re writing code, do you think about what the consequences of an exception would be if it were raised by each line of code? You have to do this if you intend to write correct code. He points out how easy it is to use exceptions to write code that is cleaner, more elegant, and wrong.
The final takeaway: exceptions are extremely powerful, easily misused, and must be carefully constrained to avoid causing very hard to find bugs in very easy to get wrong code.
Added: Be sure to read the comments to Raymond Chen’s Cleaner, More Elegant, and Wrong.