Exceptions in many languages carry messages and exceptions can be nested. There's also nothing stopping you from logging messages as you handle exceptions. The best case of exceptions is easily as good as best case go-style error handling and reporting. The worst case of exceptions is far more informative than the worst case of error messages. I'm not sure what an example that requires great use of some language facility is supposed to be illustrative of - good use of a facility is usually... good?
[Edit: this was a reply to a comment you seem to have rewritten (I think for the worse) but I think the response still mostly works]
Re:Errors in Go: From denial to acceptance
by lloeki on Tuesday November 27, 2018 @06:40AM
(#18541470)
I think this can fundamentally be summed up as:
errors are "failure as data" (hence, message), and you get to write the flow (including handling and annotating the call stack)
vs
exceptions are "failure as flow" (hence, stack trace), and you get to write the data (including logging)
May very well be paraphrasing a well known maxim about closures and objects as errors are a poor man's exceptions and exceptions are a poor man's errors.
Stack traces are not like this, you can't really control whether they are good or bad, at least not well. If you want to make your stack traces more informative what do you do? You can't really change them, they just reflect your call graph.
Golang optimizes for the case where you get good error messages. Exceptions optimize for the case where you don't care about adding context to the error and just want to bubble it upwards. On the balance of things, I prefer Golang's approach because most of the time, I don't want to see the stack trace.