3 ms·
I use Go professionally and like it on balance, but error handling is my least favorite part of it. * In practice there are not that many ways of combining fal
by closeparen 7y ago
I use Go professionally and like it on balance, but error handling is my least favorite part of it.
* In practice there are not that many ways of combining fallible operations. "if err != nil { return nil, err }" is the right thing 99% of the time. Occasionally you might want to perform a set of independent operations (probably in parallel) and then handle their errors as a group. It's almost never the right thing to write complex, arbitrary logic about combinations of error values, or to ignore them. Go makes the wrong things too easy and requires the right thing to be spelled out explicitly each time. Somewhat mitigated by lint rules and editor macros, respectively, but still.
* Wrapping your errors produces great messages but defeats type switches for structured error handling. This pattern makes it easy to not actually have the error handling logic that that appears to be there.
* You need to be very careful about adding context, because you need your error monitoring system (Sentry, etc) to understand what are instances of the same failure mode vs. different failure modes. I find I can't really put any more information in the Error() string than would be in a stacktrace, or the cardinality of "unique" errors blows up. You can attach information to custom error structs and report it in dedicated log fields, but then upper layers need to know how to unroll the error stack (e.g. errors.Cause()) and access those fields.
- ainar-g 7y ago> Wrapping your errors produces great messages but defeats type switches for structured error handling. This pattern makes it easy to not actually have the error handling logic that that appears to be there. Not true. I've been successfully using error wrapping with type switches for years. That's what unwrapping is for. Go 1.13 has functions errors.Is(error) bool and errors.As(error, interface{}) bool and also errors.Unwrap(error) error. Package github.com/pkg/errors, which I use, only has function errors.Cause(error) error, but writing your own inspection helpers is trivial. > You need to be very careful about adding context, because you need your error monitoring system (Sentry, etc) to understand what are instances of the same failure mode vs. different failure modes. (…) Not sure about Sentry, but Airbrake has no issues with that.