Skip to content

Instantly share code, notes, and snippets.

@ChrisHines
Last active September 1, 2018 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChrisHines/a732a9b1ef3acb6acfee2ccc174e31ed to your computer and use it in GitHub Desktop.
Save ChrisHines/a732a9b1ef3acb6acfee2ccc174e31ed to your computer and use it in GitHub Desktop.
Types cannot implement both the errors.Formatter and fmt.Formatter interfaces

The draft design defines a new errors.Formatter interface as follows.

package errors

// A Formatter formats error messages.
type Formatter interface {
	// Format is implemented by errors to print a single error message.
	// It should return the next error in the error chain, if any.
	Format(p Printer) (next error)
}

Unfortunately the choice of Format for the method name conflicts with method defined by the fmt.Formatter interface by using the same method name with a different signature. Existing error packages such as github.com/pkg/errors define error types that already implement fmt.Formatter that would need to change in a backwards incompatible way in order to participate in the suggested error formatting paradigm.

Another example is the package github.com/go-stack/stack. It introduced the idea of implementing fmt.Formatter for controlling the level of detail when printing stack information. It also directly inspired that idea for errors in github.com/pkg/errors. It would make sense for package github.com/go-stack/stack to implement errors.Formatter alongside fmt.Formatter so that it could be used as a helper for custom error types. Package github.com/go-stack/stack has other uses outside of error reporting that would likely want to continue using the fmt.Formatter implementation.

I suggest changing the errors.Formatter interface to the following to avoid the conflict described above.

package errors

// A Formatter formats error messages.
type Formatter interface {
	// FormatError is implemented by errors to print a single error message.
	// It should return the next error in the error chain, if any.
	FormatError(p Printer) (next error)
}
@mpvl
Copy link

mpvl commented Sep 1, 2018

This conflict was actually introduced by design. It would be very confusing for a type to support both. Which Formatter would package fmt pick if a type could support both?

As for backwards compatibility, how do you think this would be a problem? Backwards compatibility is inevitably broken as the order of printing will change for pkg/errors. I think it is an acceptable trade off for both cases though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment