←back to thread

628 points kiyanwang | 1 comments | | HN request time: 0.56s | source
1. jrockway ◴[] No.43630673[source]
Reading the error message is a good idea. I try to make the fragments of my error messages unique so that in some error like "foo the bar: get bar: lookup bar source: i/o timeout" you can search for "lookup bar source" and get the one point in the code that the error actually came from. (In go, this involves error wrapping and adding the minimum necessary context at each level.) This survives minor refactors (whereas line numbers don't) and cross-subsystem or cross-subsystem errors (next time the error is "foo the bar: get bar from remote bar repository https://bar.example.com/: get bar: lookup bar source: i/o timeout"). I also obviously try to get my team to do this ;) At my last job, before I joined the team, someone said that stack traces would eliminate the need for error wrapping. They tried it. It didn't. Customers (and support) could never figure out what was going on. But adding a handful of carefully chosen words at each level? Suddenly much easier.

Reading the source code is also a great idea. You'll always pick up some good ideas from other people's code. I learned this the hard way, but also kind of the easy way... at Google, sometimes we had good documentation. Eventually I realized it was often out of date, and so just got in the habit of reading the server code that I was interacting with. Suddenly, everything was much clearer. Why does it return an error in this exact case with this exact set of circumstances? There is a condition for just that case. Set this useless flag and that block is skipped. You'll never see that in the documentation, the exact details behind why something works how it's working exists in one person's mind at one point in time, and the code is the only thing that remembers. So, ask the code.

In both cases, some easy-to-use text searching tool is helpful. I always use rg (and deadgrep inside emacs), but there are many.