From 3dc37da2ca056286d04504c2034667c7ce8f8c41 Mon Sep 17 00:00:00 2001 From: Dave Cheney Date: Thu, 9 Jun 2016 20:02:11 +1000 Subject: [PATCH] Reverse the order of Fprint output (#43) Fprint should match the stack output, innermost error first. It probably doesn't matter as Fprint is going away. --- errors.go | 25 +++++++++++-------------- errors_test.go | 41 +++++++++++++++++++++++++---------------- example_test.go | 6 +++--- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/errors.go b/errors.go index a97116f..e77e394 100644 --- a/errors.go +++ b/errors.go @@ -182,24 +182,21 @@ func Cause(err error) error { // Fprint prints the error to the supplied writer. // If the error implements the Causer interface described in Cause -// Print will recurse into the error's cause. -// If the error implements one of the following interfaces: -// -// type Stacktrace interface { -// Stacktrace() []Frame -// } -// -// Print will also print the file and line of the error. +// Fprint will recurse into the error's cause. +// Fprint will also print the file and line of the error. // If err is nil, nothing is printed. // // Deprecated: Fprint will be removed in version 0.7. func Fprint(w io.Writer, err error) { - for err != nil { - fmt.Fprintf(w, "%+v\n", err) - cause, ok := err.(causer) - if !ok { - break + var fn func(err error) + fn = func(err error) { + if err == nil { + return } - err = cause.Cause() + if cause, ok := err.(causer); ok { + fn(cause.Cause()) + } + fmt.Fprintf(w, "%+v\n", err) } + fn(err) } diff --git a/errors_test.go b/errors_test.go index 8238a85..d3780f1 100644 --- a/errors_test.go +++ b/errors_test.go @@ -119,20 +119,29 @@ func TestFprintError(t *testing.T) { want: "EOF\n", }, { // caused error returns cause - err: &causeError{cause: io.EOF}, - want: "cause error\nEOF\n", + err: &causeError{cause: io.EOF}, + want: "EOF\n" + + "cause error\n", }, { err: x, // return from errors.New want: "github.com/pkg/errors/errors_test.go:106: error\n", }, { - err: Wrap(x, "message"), - want: "github.com/pkg/errors/errors_test.go:128: message\ngithub.com/pkg/errors/errors_test.go:106: error\n", + err: Wrap(x, "message"), + want: "github.com/pkg/errors/errors_test.go:106: error\n" + + "github.com/pkg/errors/errors_test.go:129: message\n", + }, { + err: Wrap(io.EOF, "message"), + want: "EOF\n" + + "github.com/pkg/errors/errors_test.go:133: message\n", }, { - err: Wrap(Wrap(x, "message"), "another message"), - want: "github.com/pkg/errors/errors_test.go:131: another message\ngithub.com/pkg/errors/errors_test.go:131: message\ngithub.com/pkg/errors/errors_test.go:106: error\n", + err: Wrap(Wrap(x, "message"), "another message"), + want: "github.com/pkg/errors/errors_test.go:106: error\n" + + "github.com/pkg/errors/errors_test.go:137: message\n" + + "github.com/pkg/errors/errors_test.go:137: another message\n", }, { - err: Wrapf(x, "message"), - want: "github.com/pkg/errors/errors_test.go:134: message\ngithub.com/pkg/errors/errors_test.go:106: error\n", + err: Wrapf(x, "message"), + want: "github.com/pkg/errors/errors_test.go:106: error\n" + + "github.com/pkg/errors/errors_test.go:142: message\n", }} for i, tt := range tests { @@ -198,20 +207,20 @@ func TestStack(t *testing.T) { want []fileline }{{ New("ooh"), []fileline{ - {"github.com/pkg/errors/errors_test.go", 200}, + {"github.com/pkg/errors/errors_test.go", 209}, }, }, { Wrap(New("ooh"), "ahh"), []fileline{ - {"github.com/pkg/errors/errors_test.go", 204}, // this is the stack of Wrap, not New + {"github.com/pkg/errors/errors_test.go", 213}, // this is the stack of Wrap, not New }, }, { Cause(Wrap(New("ooh"), "ahh")), []fileline{ - {"github.com/pkg/errors/errors_test.go", 208}, // this is the stack of New + {"github.com/pkg/errors/errors_test.go", 217}, // this is the stack of New }, }, { func() error { return New("ooh") }(), []fileline{ - {"github.com/pkg/errors/errors_test.go", 212}, // this is the stack of New - {"github.com/pkg/errors/errors_test.go", 212}, // this is the stack of New's caller + {"github.com/pkg/errors/errors_test.go", 221}, // this is the stack of New + {"github.com/pkg/errors/errors_test.go", 221}, // this is the stack of New's caller }, }, { Cause(func() error { @@ -219,9 +228,9 @@ func TestStack(t *testing.T) { return Errorf("hello %s", fmt.Sprintf("world")) }() }()), []fileline{ - {"github.com/pkg/errors/errors_test.go", 219}, // this is the stack of Errorf - {"github.com/pkg/errors/errors_test.go", 220}, // this is the stack of Errorf's caller - {"github.com/pkg/errors/errors_test.go", 221}, // this is the stack of Errorf's caller's caller + {"github.com/pkg/errors/errors_test.go", 228}, // this is the stack of Errorf + {"github.com/pkg/errors/errors_test.go", 229}, // this is the stack of Errorf's caller + {"github.com/pkg/errors/errors_test.go", 230}, // this is the stack of Errorf's caller's caller }, }} for _, tt := range tests { diff --git a/example_test.go b/example_test.go index 041a75b..57f8021 100644 --- a/example_test.go +++ b/example_test.go @@ -49,10 +49,10 @@ func ExampleFprint() { err := fn() errors.Fprint(os.Stdout, err) - // Output: github.com/pkg/errors/example_test.go:36: outer - // github.com/pkg/errors/example_test.go:35: middle + // Output: github.com/pkg/errors/example_test.go:33: error // github.com/pkg/errors/example_test.go:34: inner - // github.com/pkg/errors/example_test.go:33: error + // github.com/pkg/errors/example_test.go:35: middle + // github.com/pkg/errors/example_test.go:36: outer } func ExampleWrapf() {