Commit 444039e0 authored by Damien Neil's avatar Damien Neil

fmt: fix %d and other non-string verbs on errors

When formatting an error with a non-string formatting verb such as %d,
use the default formatting behavior rather than treating this as a bad
verb.

For example, this should print 42, not %!d(main.E=42):

  var E int
  func (E) Error() string { return "error" }
  fmt.Printf("%d", E(42))

Fixes #30472

Change-Id: I62fd309c8ee9839a69052b0ec7f1808449dcee8e
Reviewed-on: https://go-review.googlesource.com/c/164557Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 72d24a74
......@@ -130,8 +130,7 @@ func fmtError(p *pp, verb rune, err error) (handled bool) {
w = newPrinter()
defer w.free()
default:
w.badVerb(verb)
return true
return false
}
}
......
......@@ -327,7 +327,7 @@ func TestErrorFormatter(t *testing.T) {
}, {
err: &wrapped{"simple", nil},
fmt: "%🤪",
want: "%!🤪(*fmt_test.wrapped=&{simple <nil>})",
want: "&{%!🤪(string=simple) <nil>}",
}, {
err: formatError("use fmt.Formatter"),
fmt: "%#v",
......@@ -345,6 +345,14 @@ func TestErrorFormatter(t *testing.T) {
err: fmtTwice("%o %s", panicValue{}, "ok"),
fmt: "%s",
want: "{} ok/{} ok",
}, {
err: intError(4),
fmt: "%v",
want: "error 4",
}, {
err: intError(4),
fmt: "%d",
want: "4",
}}
for i, tc := range testCases {
t.Run(fmt.Sprintf("%d/%s", i, tc.fmt), func(t *testing.T) {
......@@ -434,6 +442,15 @@ func (e detail) FormatError(p errors.Printer) (next error) {
return e.next
}
type intError int
func (e intError) Error() string { return fmt.Sprint(e) }
func (e intError) FormatError(p errors.Printer) (next error) {
p.Printf("error %d", e)
return nil
}
// formatError is an error implementing Format instead of errors.Formatter.
// The implementation mimics the implementation of github.com/pkg/errors.
type formatError string
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment