That makes even less sense becasue go errors provide even less info other then a chain of messages. They might as well be lists of strings. You can maybe reassbmle a call stack your self if all of the error handlers are vigalente about wrapping
They should have made the point about knowing where errors will happen.
The cherry on top is that you always have a place to add context, but it's not the main point.
In the Python example, anything can fail anywhere. Exceptions can be thrown from deep inside libraries inside libraries and there's no good way to write code that exhaustively handles errors ahead of time. Instead you get whack-a-mole at runtime.
In Go, at least you know where things will fail. It's the poor man's impl of error enumeration, but you at least have it. The error that lib.foo() returned might be the dumbest error in the world (it's the string "oops") but you know lib.foo() would error, and that's more information you have ahead of time than in Python.
In Rust or, idk, Elm, you can do something even better and unify all downstream errors into an exhaustive AGDT like RequestError = NetworkError(A | B | C) | StreamError(D | E) | ParseError(F | G) | FooError, where ABCDEFG are themselves downstream error types from underlying libraries/fns that the request function calls.
Now the callsite of `let result = request("example.com")` can have perfect foresight into all failures.
> That makes even less sense becasue go errors provide even less info other then a chain of messages.
That doesn't make sense. Go errors provide exactly whatever information is relevant to the error. The error type is an interface for good reason. The only limiting bound on the information that can be provided is by what the computer can hold at the hardware level.
> They might as well be lists of strings.
If a string is all your error is, you're doing something horribly wrong.
Or, at very least, are trying to shoehorn Go into scripting tasks, of which it is not ideally suited for. That's what Python is for! Python was decidedly intended for scripting. Different tools for different jobs.
Go was never designed to be a scripting language. But should you, for some odd reason, find a reason to use in that that capacity, you should at least being using its exception handlers (panic/recover) to find some semblance of scripting sensibility. The features are there to use.
Which does seem to be the source of your confusion. You still seem hung up on thinking that we're talking about scripting. But clearly that's not true. Like before, if we were, we'd be looking at using Go's exception handlers like a scripting language, not the patterns it uses for systems. These are very different types of software with very different needs. You cannot reasonably conflate them.