getsentry / raven-go

Sentry client in Go
https://sentry.io
BSD 3-Clause "New" or "Revised" License
561 stars 148 forks source link

Panic if the error implements causer and the cause is nil #260

Closed misterEggroll closed 5 years ago

misterEggroll commented 5 years ago

Sample code:

import (
    "fmt"
    "github.com/getsentry/raven-go"
    pkgErrors "github.com/pkg/errors"
)

type causer interface {
    Cause() error
}

type customErr struct {
    msg   string
    cause error
}

func (e *customErr) Error() (errorMsg string) {
    if e.msg != "" && e.cause != nil {
        errorMsg = fmt.Sprintf("%v \n\t==>> %v", e.msg, e.cause)
    } else if e.msg == "" && e.cause != nil {
        errorMsg = fmt.Sprintf("%v", e.cause)
    } else if e.msg != "" && e.cause == nil {
        errorMsg = fmt.Sprintf("%s", e.msg)
    }
    return
}

// Implementing the causer interface from github.com/pkg/errors
func (e *customErr) Cause() error {
    return e.cause
}

func main() {
    _err := &customErr{
        cause: nil,
        msg:   "This is a test",
    }
    err := pkgErrors.WithStack(_err)
    raven.CaptureErrorAndWait(err, nil)
}

Output:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x12eeec6]

goroutine 1 [running]:
github.com/getsentry/raven-go.NewException(0x0, 0x0, 0xc000323200, 0x3)
    /Users/adityasatyavada/go/src/github.com/getsentry/raven-go/exception.go:11 +0x26
github.com/getsentry/raven-go.(*Client).CaptureErrorAndWait(0xc000328000, 0x1440900, 0xc000323100, 0x0, 0x0, 0x0, 0x0, 0xc000323100, 0xc0003230e0)
    /Users/adityasatyavada/go/src/github.com/getsentry/raven-go/client.go:740 +0x2fd
github.com/getsentry/raven-go.CaptureErrorAndWait(0x1440900, 0xc000323100, 0x0, 0x0, 0x0, 0x0, 0xc000147f88, 0xc000074058)
    /Users/adityasatyavada/go/src/github.com/getsentry/raven-go/client.go:751 +0x70
main.main()

Solution:

Current code: cause := Cause(err)

Proposed change:

cause := pkgErrors.Cause(err)
if cause == nil{
    cause = err
}