diff --git a/stacktrace.go b/stacktrace.go index 642569d..afd35ff 100644 --- a/stacktrace.go +++ b/stacktrace.go @@ -7,6 +7,7 @@ package raven import ( "bytes" + "fmt" "go/build" "io/ioutil" "path/filepath" @@ -49,6 +50,24 @@ type StacktraceFrame struct { InApp bool `json:"in_app"` } +// Returns a string representation of the stacktrace similar do debug.Stack() +func (s Stacktrace) String() string { + buff := &bytes.Buffer{} + for i := len(s.Frames) - 1; i >= 0; i-- { + f := s.Frames[i] + buff.WriteString(f.String()) + buff.WriteString("\n") + } + return buff.String() +} + +// Returns a string representation of the frame similar do debug.Stack() +// /path/to/file.go:37 +// funcName: lineContext("the line of code") +func (f StacktraceFrame) String() string { + return fmt.Sprintf("%s:%d\n\t%s: %s", trimPath(f.Filename), f.Lineno, f.Function, f.ContextLine) +} + // Intialize and populate a new stacktrace, skipping skip frames. // // context is the number of surrounding lines that should be included for context. diff --git a/stacktrace_test.go b/stacktrace_test.go index bdc9ab3..64aa467 100644 --- a/stacktrace_test.go +++ b/stacktrace_test.go @@ -133,3 +133,37 @@ func TestNewStacktrace_outOfBounds(t *testing.T) { t.Errorf("incorrect ContextLine: %#v", f.ContextLine) } } + +func TestStacktraceFrameString(t *testing.T) { + st := trace() + str := st.Frames[len(st.Frames)-1].String() + if !strings.Contains(str, "github.com/getsentry/raven-go/stacktrace_test.go:85") { + t.Errorf("frame.String() does not contain file and line no %s", str) + } + + if !strings.Contains(str, "trace: return NewStacktrace(0, 2, []string{thisPackage})") { + t.Errorf("frame.String() does not contain function and line context %s", str) + } +} + +func TestStacktraceString(t *testing.T) { + st := trace() + arr := strings.Split(st.String(), "\n") + + if len(arr) != 7 { + t.Errorf("incorrect length: %d", len(arr)) + } + + if !strings.Contains(arr[0], "github.com/getsentry/raven-go/stacktrace_test.go:85") { + t.Errorf("unexpected 1st line from st.String(): %s", arr[0]) + } + if !strings.Contains(arr[1], "trace: return NewStacktrace(0, 2, []string{thisPackage})") { + t.Errorf("unexpected 2nd line from st.String(): %s", arr[1]) + } + if !strings.Contains(arr[2], "github.com/getsentry/raven-go/stacktrace_test.go:150") { + t.Errorf("unexpected 3rd line from st.String(): %s", arr[2]) + } + if !strings.Contains(arr[3], "TestStacktraceString: st := trace()") { + t.Errorf("unexpected 4th line from st.String(): %s", arr[3]) + } +}