Преглед на файлове

Refactor errors.location to be a stack of callers (#25)

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.
Dave Cheney преди 10 години
родител
ревизия
daa1017c6f
променени са 1 файла, в които са добавени 15 реда и са изтрити 14 реда
  1. 15 14
      errors.go

+ 15 - 14
errors.go

@@ -55,12 +55,11 @@ import (
 	"strings"
 	"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) {
 func (l location) Location() (string, int) {
-	pc := uintptr(l) - 1
+	pc := l[0] - 1
 	fn := runtime.FuncForPC(pc)
 	fn := runtime.FuncForPC(pc)
 	if fn == nil {
 	if fn == nil {
 		return "unknown", 0
 		return "unknown", 0
@@ -110,13 +109,12 @@ func (l location) Location() (string, int) {
 
 
 // New returns an error that formats as the given text.
 // New returns an error that formats as the given text.
 func New(text string) error {
 func New(text string) error {
-	pc, _, _, _ := runtime.Caller(1)
 	return struct {
 	return struct {
 		error
 		error
 		location
 		location
 	}{
 	}{
 		errors.New(text),
 		errors.New(text),
-		location(pc),
+		caller(),
 	}
 	}
 }
 }
 
 
@@ -132,13 +130,12 @@ func (c cause) Message() string { return c.message }
 // Errorf formats according to a format specifier and returns the string
 // Errorf formats according to a format specifier and returns the string
 // as a value that satisfies error.
 // as a value that satisfies error.
 func Errorf(format string, args ...interface{}) error {
 func Errorf(format string, args ...interface{}) error {
-	pc, _, _, _ := runtime.Caller(1)
 	return struct {
 	return struct {
 		error
 		error
 		location
 		location
 	}{
 	}{
 		fmt.Errorf(format, args...),
 		fmt.Errorf(format, args...),
-		location(pc),
+		caller(),
 	}
 	}
 }
 }
 
 
@@ -148,8 +145,7 @@ func Wrap(cause error, message string) error {
 	if cause == nil {
 	if cause == nil {
 		return 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.
 // Wrapf returns an error annotating the cause with the format specifier.
@@ -158,11 +154,10 @@ func Wrapf(cause error, format string, args ...interface{}) error {
 	if cause == nil {
 	if cause == nil {
 		return 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 {
 	return struct {
 		cause
 		cause
 		location
 		location
@@ -171,7 +166,7 @@ func wrap(err error, msg string, pc uintptr) error {
 			cause:   err,
 			cause:   err,
 			message: msg,
 			message: msg,
 		},
 		},
-		location(pc),
+		loc,
 	}
 	}
 }
 }
 
 
@@ -239,3 +234,9 @@ func Fprint(w io.Writer, err error) {
 		err = cause.Cause()
 		err = cause.Cause()
 	}
 	}
 }
 }
+
+func caller() location {
+	var pcs [1]uintptr
+	n := runtime.Callers(3, pcs[:])
+	return location(pcs[0:n])
+}