Elliot Chance
2 min readSep 1, 2021

--

“When a function returns and error, you’re forced to think about what to do with it.”

I totally agree with this, in theory. In practice, at least for me, it becomes like muscle memory to just pass the error up the chain, whatever it may be. Errors have different significance, some errors are recoverable, some errors are not. Errors that are known to not be recoverable need not return an error.

I think “unexpected” is being misconstrued here. That’s probably my fault. If you can plan for the unexpected, it’s not unexpected. You are, by definition, expecting it. For example, if you know that the database goes away sometimes and you should retry, that’s great, do that. It’s no longer an unrecoverable or unexpected error based on the behavior of your application.

How often have you put protections in for a panic caused by a divide by zero, index out of bounds or nil dereference that may happen anywhere lower in the stack? That’s a real unexpected and unrecoverable error (Go literally bails out for you). Good code creates guards against these scenarios, but they still happen. You don’t want an unexpected error like this to bring down your whole server, so we put (or have provided through a framework) recover points at some boundary like the request.

All I’m saying here, is that there are some expected errors that are also unrecoverable — indicating that the application/request/whatever is an impossible state to proceed. A nil dereference or a database that’s gone are both examples of this (unless for you that’s recoverable). The request cannot proceed, so just bail out immediately, rather than endlessly passing up an error. Especially through many functions that don’t error themselves or have any understanding of what the error they’re passing up.

That does not mean you can’t return the error to the user with the same message. Log the panic (which gives you a stack trace), etc.

It’s also worth pointing out that Go is built for this style of error handling, because cleanup should always happen in a defer to ensure they do run regardless of panic or success all the way up the chain.

--

--

Elliot Chance
Elliot Chance

Written by Elliot Chance

I’m a data nerd and TDD enthusiast originally from Sydney. Currently working for Uber in New York. My thoughts here are my own. 🤓 elliotchance@gmail.com

No responses yet