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())
}