The implementation of WithMeta() is flawed. Not only is it not concurrency-safe, every nested call will be modifying the parent map. The way to do this in a safe and performant manner is to structure the metadata as a tree, with a parent pointing to the previous metadata. You'd probably want to do some pooling and other optimizations to avoid allocating a map every time. Then all the maps can be immutable and therefo…
Just a little more work, and you will reinvent exceptions with stack traces! Proper error handling in Go is now tantalisingly close!
Structured Errors in Go (2022)
51–60 of 75 posts
Re: Structured Errors in Go (2022)
#52Earlier quoted context omitted.
err.(type) fails when errors are wrapped, which is common and needs to be accommodated. To do what you're trying to do, you need to use errors.As.
Sure. It was not intended to be a complete example.
Re: Structured Errors in Go (2022)
#53Alright, so this looks pretty comprehensive for error handling. But I gotta ask – for smaller to mid-size projects, is there a point where this level of structure becomes more work than it's worth?
IMO error handling is the sort of thing you really want to get right early on, even in toy projects. It’s very hard to retrofit, and the actual payoff is low until you need it - at which point you definitely don’t want to do the work. As antithetical as it might be, I tend to just stuff sentry in (no affiliation just a happy user) when I’m setting up the scaffolding, and insert rich context at the edges (in the route…
Re: Structured Errors in Go (2022)
#54One thing that seemingly is missing is the ability to tag a specific error with an error code. You typically want to know that all of a sudden the ”failed to get user” error is being returned a lot. Since the message is a dynamic string you can’t just group by the string so unless you build it as part of your abstraction it becomes very hard to do. Edit: looking more carefully at the lib I assume that ”tag” is the co…
in standard go you'd have errors implement: func (myError) Is(err error) bool and it can match different sentinel errors. Or you can make your own wrapper to have the error chain match.
Re: Structured Errors in Go (2022)
#55Earlier quoted context omitted.
in standard go you'd have errors implement: func (myError) Is(err error) bool and it can match different sentinel errors. Or you can make your own wrapper to have the error chain match.
In standard go you would not implement Is but would use the errors.Is call. How would this work if it is a sentinel error as you would use with errors.Is??
> An error is considered to match a target if it is equal to that target or if it implements a method Is(error) bool such that Is(target) returns true.
by default errors.Is matches the exact error variable, but you can use it to match other errors as well.
Re: Structured Errors in Go (2022)
#56Earlier quoted context omitted.
In standard go you would not implement Is but would use the errors.Is call. How would this work if it is a sentinel error as you would use with errors.Is??
https://pkg.go.dev/errors#Is > An error is considered to match a target if it is equal to that target or if it implements a method Is(error) bool such that Is(target) returns true. by default errors.Is matches the exact error variable, but you can use it to match other errors as well.
Re: Structured Errors in Go (2022)
#57Earlier quoted context omitted.
Sure. It was not intended to be a complete example.
It's not that the example is incomplete, it's that it's incorrect! :)
for err != nil {
switch e := err.(type) {
case UserNotFound:
writeJSONResponse(w, 404, "User not found")
return
case interface { Timeout() bool }:
if e.Timeout() {
writeJSONResponse(w, 503, "Timeout")
return
}
}
err = errors.Unwrap(err)
}Re: Structured Errors in Go (2022)
#58These are good general tips applicable to other languages too. I strongly dislike when code returns errors as arbitrary strings rather than classes, as it makes errors extremely difficult to handle; one would presumably want to handle a http 502 diffrernetly to a 404, but if a programmer returns that in a string, I have to do some wonky regex instead of checking the type of error class (or pulling a property from an…
Re: Structured Errors in Go (2022)
#59Earlier quoted context omitted.
IMO error handling is the sort of thing you really want to get right early on, even in toy projects. It’s very hard to retrofit, and the actual payoff is low until you need it - at which point you definitely don’t want to do the work. As antithetical as it might be, I tend to just stuff sentry in (no affiliation just a happy user) when I’m setting up the scaffolding, and insert rich context at the edges (in the route…
why do you think it's hard to retrofit? it's just an SDK to setup up, right (point at some DSN)?
Re: Structured Errors in Go (2022)
#60Not a Go engineer but Go-curious - shouldn’t this use slog[0] for structured logging rather than a third party?
Depends on if you're making a public library. Using slog is "polite" but I don't really see it as the endgame of logging libraries. It has quite a few rough edges for CLI apps, like no control on attr order. But it is zomgfast, and speed is important, right?