raven-go
raven-go copied to clipboard
raven-go obscures panic error message
If I call panic, usually that error message appears in the stack trace.
package main
func main() {
panic("error occurred")
}
Generates:
panic: error occurred
goroutine 1 [running]:
panic(0x56000, 0xc42000a130)
/Users/kevin/go/src/runtime/panic.go:500 +0x1a1
main.main()
/Users/kevin/foo.go:4 +0x6d
exit status 2
However when I use the RecoveryHandler, I get an empty panic message in the stack trace - I have to check my email or log into Sentry to actually see what the panic was.
Example:
goroutine 44 [running]:
runtime/debug.Stack(0x0, 0x3bb8a5e2010def0, 0x1c5243)
/Users/kevin/go/src/runtime/debug/stack.go:24 +0x79
runtime/debug.PrintStack()
/Users/kevin/go/src/runtime/debug/stack.go:16 +0x22
github.com/saintpete/logrole/vendor/github.com/getsentry/raven-go.RecoveryHandler.func1.1(0xc420746c30, 0x791be0, 0xc42023ee70)
/Users/kevin/code/go/src/github.com/saintpete/logrole/vendor/github.com/getsentry/raven-go/http.go:74 +0x6e
panic(0x46d360, 0xc4204691a0)
/Users/kevin/go/src/runtime/panic.go:458 +0x243
text/template.errRecover(0xc42010f248)
/Users/kevin/go/src/text/template/exec.go:146 +0x18e
That panic is generated by this code in template/exec.go:
// errRecover is the handler that turns panics into returns from the top
// level of Parse.
func errRecover(errp *error) {
e := recover()
if e != nil {
switch err := e.(type) {
case runtime.Error:
panic(e)
case writeError:
*errp = err.Err // Strip the wrapper.
case ExecError:
*errp = err // Keep the wrapper.
default:
panic(e)
}
}
}
In my email I see this:
*errors.errorString: unknown property FriendlyName
But for some reason that string is not in the generated stack trace; I expect it to say something like:
goroutine 44 [running]: unknown property FriendlyName
This code in http.go:
if rval := recover(); rval != nil {
debug.PrintStack()
rvalStr := fmt.Sprint(rval)
packet := NewPacket(rvalStr, NewException(errors.New(rvalStr), NewStacktrace(2, 3, nil)), NewHttp(r))
Capture(packet, nil)
w.WriteHeader(http.StatusInternalServerError)
}
I believe should also call fmt.Println("panic:", rval) before debug.PrintStack()
FWIW, here's how the Go standard library prints panics.
// For calling from C.
// Prints an argument passed to panic.
// There's room for arbitrary complexity here, but we keep it
// simple and handle just a few important cases: int, string, and Stringer.
func printany(i interface{}) {
switch v := i.(type) {
case nil:
print("nil")
case stringer:
print(v.String())
case error:
print(v.Error())
case int:
print(v)
case string:
print(v)
default:
print("(", typestring(i), ") ", i)
}
}
This is how it looks like in the dashboard:

Was expecting runtime error: invalid memory address or nil pointer dereference