errors/fmt: avoid printing spurious colon
This happened when Detail is called but nothing
is printed.
Also gobble a newline at the start of printing detail.
Gobbling a newline at either the start or end simplifies
implementations, such as printing a list of stack traces.
Change-Id: I01af5c219745104600d01f9b543a054e7c1385f1
Reviewed-on: https://go-review.googlesource.com/c/152998
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/errors/fmt/errors.go b/errors/fmt/errors.go
index 4bc00b3..3150cc5 100644
--- a/errors/fmt/errors.go
+++ b/errors/fmt/errors.go
@@ -201,7 +201,18 @@
func (p *errPPState) Write(b []byte) (n int, err error) {
if !p.fmt.inDetail || p.fmt.plusV {
k := 0
+ if len(b) == 0 {
+ return 0, nil
+ }
if p.fmt.indent {
+ if p.fmt.needNewline {
+ p.fmt.needNewline = false
+ p.buf.WriteByte(':')
+ p.buf.Write(detailSep)
+ if b[0] == '\n' {
+ b = b[1:]
+ }
+ }
for i, c := range b {
if c == '\n' {
p.buf.Write(b[k:i])
@@ -243,7 +254,7 @@
p.fmt.inDetail = true
p.fmt.indent = p.fmt.plusV
if p.fmt.plusV && !inDetail {
- (*errPPState)(p).Write([]byte(":\n"))
+ p.fmt.needNewline = true
}
return p.fmt.plusV
}
diff --git a/errors/fmt/errors_test.go b/errors/fmt/errors_test.go
index 4757ac8..6a0ce27 100644
--- a/errors/fmt/errors_test.go
+++ b/errors/fmt/errors_test.go
@@ -232,6 +232,23 @@
"\nnewline: and another" +
"\none",
}, {
+ err: spurious(""),
+ fmt: "%s",
+ want: "spurious",
+ }, {
+ err: spurious(""),
+ fmt: "%+v",
+ want: "spurious",
+ }, {
+ err: spurious("extra"),
+ fmt: "%s",
+ want: "spurious",
+ }, {
+ err: spurious("extra"),
+ fmt: "%+v",
+ want: "spurious:\n" +
+ " extra",
+ }, {
err: nil,
fmt: "%+v",
want: "<nil>",
@@ -344,6 +361,21 @@
return nil
}
+type spurious string
+
+func (e spurious) Error() string { return fmt.Sprint(e) }
+
+func (e spurious) Format(p errors.Printer) (next error) {
+ p.Print("spurious")
+ p.Detail() // Call detail even if we don't print anything
+ if e == "" {
+ p.Print()
+ } else {
+ p.Print("\n", string(e)) // print extraneous leading newline
+ }
+ return nil
+}
+
// formatError is an error implementing Format instead of errors.Formatter.
// The implementation mimics the implementation of github.com/pkg/errors,
// including that
diff --git a/errors/fmt/format.go b/errors/fmt/format.go
index 83872fe..f79301e 100644
--- a/errors/fmt/format.go
+++ b/errors/fmt/format.go
@@ -35,9 +35,10 @@
plusV bool
sharpV bool
- // error-related flags. plusV indicates detail mode.
- inDetail bool
- indent bool
+ // error-related flags.
+ inDetail bool
+ indent bool
+ needNewline bool
}
// A fmt is the raw formatter used by Printf etc.