- you can collect errors in a function and return them once or provide an extra method, like http://golang.org/pkg/bufio/#Scanner.Err
- you can type switch on the error; maybe there are errors that you can recover/retry locally, such as connection errors, or general io failures - so you do not need to pass back all errors to the caller
More on errors: https://blog.golang.org/errors-are-values
I feel like so many developers have been so damaged by Java's approach to exception handling that, of course, error codes seem simpler by comparison. I can't help by feel the recent push-back against exceptions is a step backwards in many situations. A whole generation of developers will have to re-learn the pain that lead to the development of exceptions in the first place.
I do find littering code with err checks can be annoying and ended up reaching a compromise. For all code that is likely to be part of an externally public package I use 'if err !=' checks. For application level code that will be internal to my application (and internal to the file I'm working in) I use a small library [1] I wrote, that uses the panic-defer-recover style talked about in the Go documents for internal error handling [2].
However, I find that in most situations I usually prefer to not use panic-defer-recover, with if checks providing more clarity.
[1] https://github.com/surullabs/fault [2] http://golang.org/doc/effective_go.html#recover
If I'm doing something wrong here I'd love to know it.