Program gets bad or unexpected input (parsers, tokenizers, renderers, data processing): parse or process as much valid input as possible, then set a helpful error condition and return.
Program encounters a resource constraint (malloc failed, can't get a lock, no socket available, permissions problem): set a helpful error condition and return.
Something really went bugnuts (kernel panic): crash, but as gracefully as possible.
Raising exceptions is an OK way to transmit errors up the call chain, although it's not my personal favorite, but allowing unhandled exceptions to find their way up the call chain doesn't seem like a great idea to me.
edit: I went back and re-re-read the post. His points here seem reasonable:
> Do I know how I’m supposed to handle an error here?
> If not, then should I handle it? (Thus going back to specification)
etc., but I don't understand the code example at the end; I'd think it would be good to have more precise information about what failed and where and why, rather than omitting that exception handling and letting a parent process or something else deal with it further up the chain where the cause is far more opaque.