errors: detect unknown frames correctly (#192)
With Go 1.12, we will now be doing mid-stack inlining. This exposes
inlined frames to runtime.Callers and friends.
The spec says that a runtime.Frame may have a nil Func field for
inlined functions. Instead, use the Function field to detect whether
we really have an empty Frame.
diff --git a/format_test.go b/format_test.go
index c2eef5f..fd35ca3 100644
--- a/format_test.go
+++ b/format_test.go
@@ -360,6 +360,30 @@
}
}
+func wrappedNew(message string) error { // This function will be mid-stack inlined in go 1.12+
+ return New(message)
+}
+
+func TestFormatWrappedNew(t *testing.T) {
+ tests := []struct {
+ error
+ format string
+ want string
+ }{{
+ wrappedNew("error"),
+ "%+v",
+ "error\n" +
+ "github.com/pkg/errors.wrappedNew\n" +
+ "\t.+/github.com/pkg/errors/format_test.go:364\n" +
+ "github.com/pkg/errors.TestFormatWrappedNew\n" +
+ "\t.+/github.com/pkg/errors/format_test.go:373",
+ }}
+
+ for i, tt := range tests {
+ testFormatRegexp(t, i, tt.error, tt.format, tt.want)
+ }
+}
+
func testFormatRegexp(t *testing.T, n int, arg interface{}, format, want string) {
got := fmt.Sprintf(format, arg)
gotLines := strings.SplitN(got, "\n", -1)
diff --git a/stack.go b/stack.go
index 3b582c2..5be4627 100644
--- a/stack.go
+++ b/stack.go
@@ -35,11 +35,10 @@
case 's':
switch {
case s.Flag('+'):
- fn := f.Func
- if fn == nil {
+ if f.Function == "" {
io.WriteString(w, "unknown")
} else {
- io.WriteString(w, fn.Name())
+ io.WriteString(w, f.Function)
io.WriteString(w, "\n\t")
io.WriteString(w, f.File)
}