Workerbee Simone saw a weird error on Beeminder one day and sent me this screenshot:

That rang no bells but naturally I grepped the source code for “ERROR_0304” and found this:
return "ERROR_0304" // passed in bad format string; should never happen
My past self was saying, “if this ever happens, which it totally won’t but, y’know, if, then my future self should immediately get pointed at this line of code”. And that is what happened.
This could be too simple and obvious to blog about but until now, googling “greppable errors” wasn’t turning up anything (not anything human-written anyway) to explain it. So, you’re welcome, Internet.
(Also, “grep” is the nerdier term for “control-f”.)
If you’re curious where the “_0304” suffix came from, it was purely to make sure the string would be unique and greppable. I generally use the hour and minute of whatever my watch says as I’m typing, so apparently wrote that line of code at 3am, as I’m wont to do. The point is, it serves as a crude but good enough Universally Unique Identifer (UUID). Ok, not literally universally unique but more than good enough. It’s a safe bet that after we’ve hit publish on this blog post, searching “ERROR_0304” across the whole wide internet will bring you right here.
(Relatedly, it never ceases to amaze me that that’s true for most five-word snippets from any random sentence from any page on the whole internet. Go ahead, try googling “for most five-word snippets”. As I type this, it matches zero documents on the internet so presumably as you read this, it brings you right back here.)
A hierarchy of errors
Here’s another obvious thing. Errors want to be as high on this list as possible:
- Fail never (reserved for God and Mary Poppins)
- Fail gracefully
- Fail loudly
- Fail opaquely
- Fail silently
Greppable errors help you avoid the bottom two levels, yielding loud failures that leave a nice breadcrumb trail for fixing or improving them.
Like if you’re adding a sanity-check in your code — e.g., you are conscientiously checking that a file exists before trying to read its contents — start by catching that exception in a way that the end user will point you to the place in the code where the check failed. Maybe later you’ll decide that’s too embarrassing and can add logic to fail more gracefully than that. But the worst of all is to fail silently and the second worst is to fail opaquely. Almost-best is to fail loudly. If it’s really worth it, the best, short of apotheosis, is to fail gracefully.
In conclusion, here are some specific implications and advice:
- Do error-checking! Make sure a file exists before you try to read from it. Use your napkin at the dinner table. Basic manners and hygiene!
- Don’t just print “file not found”, use a greppable error that points you at the right place in the code.
- Follow the Anti-Robustness Principle aka Anti-Postel: make everything break loudly when there’s an error.
- YAGNI. Don’t speculate and anticipate. Fail loudly and greppably first and wait to see those failures in the wild before refining your error handling.
- I like to take this to its logical conclusion: Instead of “fallback handling”, do asserts that force a crash. Sprinkle asserts liberally throughout your code. See also offensive programming. (Emphasis on the first syllable of “offensive”; not like error messages with slurs.)