Errors in Go have been queryable chains since 1.13; it's pretty seamless with `%w`. Rust has the `?` shorthand, which is very convenient, but also the annoyance of type matching errors, particularly across different libraries, to the point where third-party error handling libraries like `anyhow` are pretty important. Leaving nil itself out of the picture (obviously, I'd rather Go had Option types), I don't know that either language has a definitive edge here.
Errors in modern Go are definitely not just strings.
Before wrapped errors in Go, this would have been an easier case to make against the language.
Anyhow's tagline is literally "a better Box<dyn Error>", which gets you nearly the same result modulo some pretty printing.
Yes, Anyhow is almost as easy to use as Go's current error handling.
You're significantly more experienced than me, so I'll defer to you here. What you're saying doesn't make sense to me though.
You're probably more experienced than I am with Rust!
I might be misunderstanding go, but I think the big difference is you use anyhow to get looses error handling at the edges of binaries. It'd be weird to see in a published library, and unusual to see deep in an internal library that supports a binary. Whereas in go you do that sort of error handling everywhere.
I think %w makes sense in libraries, too. They're structured errors that behave like strings. It's a neat trick.
Re:Down the Golang Nil Rabbit Hole
by tsimionescu on Tuesday March 30, 2021 @05:30AM
(#26632640)
Most errors in Go are still just strings, potentially with some comparison possible witht sentinel values like in the "io" package. As and Is give some nice tools, but its still up to documentation to decide which one to use, and different packages have different conventions for returning error types vs error values.
Most errors are probably strings since there probably is nothing you can customize as a handling for such particular error types. Now, if one could do something with a certain error class, then such error are usually not strings.
#1 has improved a bit lately, but I did get some mileage out of making my own type which carries an optional HTTP status, a severity level, the core error and an optional payload; and it implements Error(). It allows for easy logging, and can be used to return to the http client with a variety of messages.
1. Error handling. Not only is `if err == nil` (or my preferred `if _, err := foo(); err == nil`) a lot of noise, errors are completely opaque and might as well be strings.
2. Dependency management. It was a mess for a long time, go modules fixed a lot of issues in it's own way but still has problems (e.g. the "v2" workaround). My theory is they expected everyone, in some way, to "self-host" their modules (like how Java would have com.google.foo.bar, eventually everyone else would have "http://go.company/package", but GitHub became central repository of software for everyone and linking directly to packages was no longer sound).