Remove the errors.e type (#11) * rename loc type to location * move locationer interface inside Fprint, rename to location * refactor Wrap/Wrapf into helper method * remove errors.e type, compose an anon struct in wrap and add a Message() interface method to extract the cause message
diff --git a/errors.go b/errors.go index 00f8df1..ab22199 100644 --- a/errors.go +++ b/errors.go
@@ -56,9 +56,11 @@ "strings" ) -type loc uintptr +// location represents a program counter that +// implements the Location() method. +type location uintptr -func (l loc) Location() (string, int) { +func (l location) Location() (string, int) { pc := uintptr(l) - 1 fn := runtime.FuncForPC(pc) if fn == nil { @@ -112,26 +114,21 @@ pc, _, _, _ := runtime.Caller(1) return struct { error - loc + location }{ errors.New(text), - loc(pc), + location(pc), } } -type e struct { +type cause struct { cause error message string - loc } -func (e *e) Error() string { - return e.message + ": " + e.cause.Error() -} - -func (e *e) Cause() error { - return e.cause -} +func (c cause) Error() string { return c.Message() + ": " + c.Cause().Error() } +func (c cause) Cause() error { return c.cause } +func (c cause) Message() string { return c.message } // Wrap returns an error annotating the cause with message. // If cause is nil, Wrap returns nil. @@ -140,11 +137,7 @@ return nil } pc, _, _, _ := runtime.Caller(1) - return &e{ - cause: cause, - message: message, - loc: loc(pc), - } + return wrap(cause, message, pc) } // Wrapf returns an error annotating the cause with the format specifier. @@ -154,10 +147,19 @@ return nil } pc, _, _, _ := runtime.Caller(1) - return &e{ - cause: cause, - message: fmt.Sprintf(format, args...), - loc: loc(pc), + return wrap(cause, fmt.Sprintf(format, args...), pc) +} + +func wrap(err error, msg string, pc uintptr) error { + return struct { + cause + location + }{ + cause{ + cause: err, + message: msg, + }, + location(pc), } } @@ -187,10 +189,6 @@ return err } -type locationer interface { - Location() (string, int) -} - // Print prints the error to Stderr. // If the error implements the Causer interface described in Cause // Print will recurse into the error's cause. @@ -209,15 +207,21 @@ // The format of the output is the same as Print. // If err is nil, nothing is printed. func Fprint(w io.Writer, err error) { + type location interface { + Location() (string, int) + } + type message interface { + Message() string + } + for err != nil { - location, ok := err.(locationer) - if ok { - file, line := location.Location() + if err, ok := err.(location); ok { + file, line := err.Location() fmt.Fprintf(w, "%s:%d: ", file, line) } switch err := err.(type) { - case *e: - fmt.Fprintln(w, err.message) + case message: + fmt.Fprintln(w, err.Message()) default: fmt.Fprintln(w, err.Error()) }