Skip to content

Commit

Permalink
Refactor errors.location to be a stack of callers (pkg#25)
Browse files Browse the repository at this point in the history
Refactory errors.location to be a stack of callers rather than the
topmost caller. This is in perparation for storing the entire error
stack inside topmost error.
  • Loading branch information
davecheney committed May 23, 2016
1 parent d814416 commit daa1017
Showing 1 changed file with 15 additions and 14 deletions.
29 changes: 15 additions & 14 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,11 @@ import (
"strings"
)

// location represents a program counter that
// implements the Location() method.
type location uintptr
// location represents a stack of programm counters.
type location []uintptr

func (l location) Location() (string, int) {
pc := uintptr(l) - 1
pc := l[0] - 1
fn := runtime.FuncForPC(pc)
if fn == nil {
return "unknown", 0
Expand Down Expand Up @@ -110,13 +109,12 @@ func (l location) Location() (string, int) {

// New returns an error that formats as the given text.
func New(text string) error {
pc, _, _, _ := runtime.Caller(1)
return struct {
error
location
}{
errors.New(text),
location(pc),
caller(),
}
}

Expand All @@ -132,13 +130,12 @@ func (c cause) Message() string { return c.message }
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
func Errorf(format string, args ...interface{}) error {
pc, _, _, _ := runtime.Caller(1)
return struct {
error
location
}{
fmt.Errorf(format, args...),
location(pc),
caller(),
}
}

Expand All @@ -148,8 +145,7 @@ func Wrap(cause error, message string) error {
if cause == nil {
return nil
}
pc, _, _, _ := runtime.Caller(1)
return wrap(cause, message, pc)
return wrap(cause, message, caller())
}

// Wrapf returns an error annotating the cause with the format specifier.
Expand All @@ -158,11 +154,10 @@ func Wrapf(cause error, format string, args ...interface{}) error {
if cause == nil {
return nil
}
pc, _, _, _ := runtime.Caller(1)
return wrap(cause, fmt.Sprintf(format, args...), pc)
return wrap(cause, fmt.Sprintf(format, args...), caller())
}

func wrap(err error, msg string, pc uintptr) error {
func wrap(err error, msg string, loc location) error {
return struct {
cause
location
Expand All @@ -171,7 +166,7 @@ func wrap(err error, msg string, pc uintptr) error {
cause: err,
message: msg,
},
location(pc),
loc,
}
}

Expand Down Expand Up @@ -239,3 +234,9 @@ func Fprint(w io.Writer, err error) {
err = cause.Cause()
}
}

func caller() location {
var pcs [1]uintptr
n := runtime.Callers(3, pcs[:])
return location(pcs[0:n])
}

0 comments on commit daa1017

Please sign in to comment.