Hacker News new | ask | show | jobs
by nickcw 2613 days ago
This (it looks like to me) is an attempt to pull in the best bits of Dave Cheney's errors package (which I love) into the standard library: https://github.com/pkg/errors

Standardising error unwrapping is a great idea IMHO and I think that this has a lot of merit.

I don't like the `fmt.Errorf("more description: %w", err)` though for several reasons.

Firstly it is a lot more opaque than Dave Cheney's original mechanism errors.Wrap(err, "more description"). You've got to check the format string for a `%w` to see if it is wrapping an error or not.

Secondly why is this really important functionality in `fmt` and not in `error`?

And finally we've been encouraged to write `fmt.Errorf("more description: %v", err)` (note `%v` not `%w`), so I think there will be a lot of unwrapped errors.

...

I'm not sure enough has been thought about the backwards incompatibility. With rclone I try to maintain compatibility with the current go release and a few previous ones so that rclone can remain running with distro go versions and gccgo both of which are a bit behind. For something as common as error handling this will cause lots of libraries to suddenly be no longer usable with anything less than go1.13.

IMHO I think this would be better staying as a non standard library package for the time being while more kinks are worked out.

5 comments

Also note that the library checks for `: %w` at the end of the format string to enable this wrapping feature. If you use "%w" anywhere else in the format string it won't work.

Yuck.

Yeah, that's the only thing I don't like about this proposal. Just seems so fragile.
The go vet command checks format strings. I expect that the command will be updated to check for correct use of %w.
What's the point of making it a format string if you are hardcoding where the % identifier goes anyway?!
The %w (or %v) identifier must be at the end for the magic to work, but you can still meaningfully format things in front of the wrapped error, e.g. fmt.Errorf("Write(%s): %w", filename, err)
Why does it need to be at the end?
forward compatibility?
>Secondly why is this really important functionality in `fmt` and not in `error`?

`fmt` already depends on `errors`, and Go does not allow cyclical dependencies, so `errors` would have to reimplement string formatting.

Or they could move the machinery into a shared module.

Which already exists incidentally, internal/errinternal was added so errors.New and fmt.Errorf could return the same type.

It does make errors pull the entire formatting machinery, but chances are you're probably using string formatting long before errors so meh…

Why? Go permits mutual recursion, and "go tool link" seems to support separate compilation that would resolve that cycle.
That's not an argument for putting it in fmt.

That's an argument for putting it in the language layer or putting it in its own place.

+1 on all of this. I really prefer that https://github.com/pkg/errors is outside of the standard library so I don't need to use the fmt.Errorf abomination.
IMHO they should either just adopt Dave Cheney's errors package (https://github.com/pkg/errors) into the standard library or leave it as it is becoming the de-facto standard.

The parallel reddit thread seems to agree too: https://www.reddit.com/r/golang/comments/biexq0/go_113_xerro...

Because this isn't nodejs.
A bit offtopic how does pkg/errors compare to https://github.com/juju/errors/? I see the former is much more popular but the later seem to be nicer, I especially like the deferred annotations, since it's easy to use them to include function arguments in the stack trace.