The main problem of error handling in Go is not the tediousness of writing
if err != nil {}
after each function (it's not nice but bearable).The main problem is how hard to actually process errors.
In Go, there are three types of errors: custom structs with contextual info, predefined error constants of type stringError aka sentinels, and wrapped stringErrors, produced in-place by fmt.Errorf.
The first ones can be matched by type coersion or errors.As function. The second ones can be compared with == operator. The last ones can be either parsed by regex, or matched by the error they wrap and then unwrapped.
Oh, and the signature is nearly always just error, so basically to process errors gracefully you have to read the docs for each function instead of just looking at the signature.
It's so extremely inconvenient and tedious so nearly nobody process errors in Go, despite what language creators say. People either return error to the top of the callstack, maybe wrapping it in additional string, thus emulating poor man's exceptions without stack traces, or panic in-place. Nearly nobody catches and matches errors, as many in C++, Java, Scala or OCaml|Haskell world do.
My IDE helps a lot the typing of the error conditions and is collapsing it nicely. This is not the problem, but the error handling.
That said, with generics, it should be possible to change to the 'Either' style [0] of error handling. And with another compiler feature to be added, er, 'exhaustive switch/case' or whatever you want to call it, they can make it a compiler error to not handle the error case. That said, I don't see the language developers or community making it a standard anytime soon.
The current style of error handling doesn't hurt enough. It's verbose and repetitive, sure, but if the alternative is something clever or magic, it's not the way to go.
[0] https://www.scala-lang.org/api/2.13.6/scala/util/Either.html