Rolling your own error library is trivial. We have a great one at work that works great, prints stack traces, interops with normal error handlers, and does a lot of custom work for translating errors into external customer-visible messages and internal developer messages. We use it at every layer of a 50-60 grpc microservice ecosystem without much headache.
Catching deferred errors is trivial, not sure what you mean there:
defer func () {
err := f.Close()
...
}()Printing stack traces is like 4 lines, I was able to implement ours in 60 minutes of doc skimming. Now it'd be 5 minutes.
I don't understand your last two sentences. It doesn't reflect anything I've run into in the real world, I don't think.
I have a few gripes about golang, but the minimalist error interface is not one of them.