I would have to go through my comment history for exact numbers. In analyzing a real, production service written in Go where multiple dozens of contributors over hundreds of thousands of lines over several years, "naked" if-err-return-err made up less than 5% of error handling cases and less than 1% of total lines. Nearly every error handling case either wrapped specific context, emitted a log, and/or emitted a metric specific to that error handling situation.
If you do naked if-err-return-err, you are likely doing error handling wrong.
Plenty of The Go Way arguments apply to software we were writing from the dawn of computing until the 1990's, and there are plenty of reasons why, with exception of Go (pun intended), the industry has moved beyond that.
I nearly wrote "you are holding it wrong" to nod to that quote. But it is really true - most errors in long running services are individual and most applications I've worked in ignore this when (ab)using exceptions.
In our Go codebases, the error reporting and subsequent debugging and bug fixing is night and day from our Python, Perl, Ruby, PHP, Javascript, and Elixir experiences.
The one glaring case where this is untrue is in our usage of Helm which, having been written in Go, I would expect better error handling. Instead we get, "you have an error on line 1; good luck" - and, inspired, I looked at their code just now. Littered with empty if-err-return-err blocks - tossing out all that beautiful context, much like an exception would, but worse.
The same applies for literally any language if you care about error handling except it's way more ergonomic to do. Why do go users try to pass off the lack of language features as as if that's the reason why they care about writing quality code?
to do the same as Go in Python is way more verbose and less ergonomic because you would wrap each line in a try catch.
I can't speak for all Go users, but what I have seen is that the feature set in Go lends itself to code that handles errors, and exceptions simply don't -- I can say this because I've worked in a dozen different production systems for each of perl, python, js, elixir, and php -- I'm left believing that those languages _encourage_ bad error handling. Elixir is way cool with pattern matching and I still find myself wishing for more Go-like behavior (largely due to the lacking type system, which I hear they are working to improve).
I've not used Rust which apparently is the golden standard in the HN sphere
Wrapping a line in a try catch is equivalent to the go error check routine. Should be roughly the same amount of lines if you care about that sort of thing.
There's bad programmers everywhere. Writing if err != nil { return err } is the same as not handling exceptions (they just bubble up).
Maybe you think this because go shoves the exceptions front and center in your face and forces you to deal with them. I suppose it can be a helpful crutch for beginners but it just winds up being annoying imo.
It actually is when debugging, because it makes control flow explicit.
In JS, for example, people don‘t even know which functions could throw exceptions, and just ignore them, most of the time. Fast to write and looks nice, but is horrible quality and a nightmare to debug.
tbh only like 50% of my `if err != nil { return err }` are mindless. rest of the time, the fact that error handling is explicit and in my face has helped me alot during my time with go.
It's a tradeoff. Alternatives like exception handling make control flow less obvious and shorthands like the ? operator lock you into a specific return type (Result<T,E> in the case of Borgo or Rust).
What's bad about locking the programmer into using Result<T, E> or Option<T>? These are enough for many common use cases, and anyway, you're free to use something else and unwrap it manually.