]> Cypherpunks.ru repositories - gostls13.git/commitdiff
fmt: fix %d and other non-string verbs on errors
authorDamien Neil <dneil@google.com>
Thu, 28 Feb 2019 17:10:36 +0000 (09:10 -0800)
committerDamien Neil <dneil@google.com>
Thu, 28 Feb 2019 17:31:37 +0000 (17:31 +0000)
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/164557
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/fmt/errors.go
src/fmt/errors_test.go

index 0fd3e83814340b8524f1fc08f7291acb97b6aff6..7506b6a20b41100577795306f491cedbaf8f03ca 100644 (file)
@@ -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
                }
        }
 
index 9e6ad74697027bc927328ba41e62e61728fcfa8b..d2957e675b164bbd8672480c3e3cf656d1096990 100644 (file)
@@ -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