Honestly, I wonder if code like that just doesn't use panic / resume correctly? (Granted, I only read the book on golang about 8 years ago.)
If you mean the code that never wraps anything and just does “return
err”, then it could actually be better off using panics. In fact, it's
documented in Effective Go. If all you return in your API is
a simple opaque “shit's broken, yo” error, then it is a perfectly valid
approach to use panics. As long as they are in your package's insides,
and as long as you return an error on the external border of your API
instead of making users handle your panics.
This can be helpful, in C# there isn't even a good way to find "all functions that might throw Exception foo". In Java this is slightly better since functions must declare what they can throw.
So Go is more typing than C# style exceptions, but more clear as well. There are some middle grounds such as the Java exception approach, or the ? operator in Rust, which Go is thinking of doing something similar to that.
Exceptions also give you a stack trace, where golang errors don't (you have to jump through verbose hoops to get something barely similar). Secondly, it's much easier to ignore errors in golang, or worse, silently overwrite them (I've seen both in golang codebases). Whereas with exceptions, the exception gets bubbled up until it gets handled, or it terminates the entire program. This approach is much safer than golang's, where it's possible to end up in a corrupt state due to its subpar error handling implementation.