Skip to content

Helper function for retrieving root stack trace from error#113

Closed
creasty wants to merge 4 commits intopkg:masterfrom
creasty:creasty/expose_stack_trace
Closed

Helper function for retrieving root stack trace from error#113
creasty wants to merge 4 commits intopkg:masterfrom
creasty:creasty/expose_stack_trace

Conversation

@creasty
Copy link
Copy Markdown

@creasty creasty commented Apr 17, 2017

Why

  1. Want to retrieve function name, file and line separately.
    For now, the simplest way to do so is by using Formatter as follows.
    for _, f := range err.StackTrace() {
      file := fmt.Sprintf("%s", f)
      line, _ := strconv.ParseInt(fmt.Sprintf("%d", f), 10, 32)
      funcName := fmt.Sprintf("%n", f)
      fmt.Printf("%s at %s:%d\n", funcName, file, line)
    }
  2. These is no mechanism for extracting the root stack trace -- the longest stack trace.

Use case

Most feasible use case is an integration with error reporting systems such as honeybadger.

https://github.com/honeybadger-io/honeybadger-go/blob/f37170201ccce33edcb44f976565698c5aeb7fc4/error.go#L13-L17

type Frame struct {
	Number string `json:"number"`
	File   string `json:"file"`
	Method string `json:"method"`
}

What

Create a helper function errors.Trace which behaves like errors.Cause and returns the underlying stack trace ([]Frame) of the error.

package main

import (
	built_in_errors "errors"
	"fmt"

	"github.com/pkg/errors"
)

func foo() error {
	return built_in_errors.New("foo")
}

func bar() error {
	return errors.Wrap(foo(), "foo in bar")
}

func baz() error {
	return errors.Wrap(bar(), "bar in baz")
}

func main() {
	err := errors.Wrap(baz(), "baz in main")

	if frames := errors.Trace(err); frames != nil {
		for _, f := range frames {
			fmt.Printf("%s at %s:%d\n", f.Name(), f.File(), f.Line())
		}
	}
}
$ go run main.go
bar at /Users/ykiwng/Desktop/main.go:15
baz at /Users/ykiwng/Desktop/main.go:19
main at /Users/ykiwng/Desktop/main.go:23
main at /usr/local/Cellar/go/1.7.3/libexec/src/runtime/proc.go:183
goexit at /usr/local/Cellar/go/1.7.3/libexec/src/runtime/asm_amd64.s:2086

@martinheidegger
Copy link
Copy Markdown

This would also help to implement stack traces in sentry: getsentry/raven-go#88

@davecheney
Copy link
Copy Markdown
Member

davecheney commented Apr 18, 2017 via email

@creasty
Copy link
Copy Markdown
Author

creasty commented Apr 18, 2017

Sorry, didn't read

Contributing
...
Before proposing a change, please discuss your change by raising an issue.

@davecheney
Copy link
Copy Markdown
Member

davecheney commented Apr 18, 2017 via email

@gregwebs
Copy link
Copy Markdown

gregwebs commented Sep 10, 2018

@creasty
Copy link
Copy Markdown
Author

creasty commented Sep 11, 2018

Actually, I've created a better solution at https://github.com/srvc/fail and stopped using pkg/errors.

c.f., Create a virtual stack trace by merging multiple stack traces
srvc/fail#13

@creasty creasty closed this Sep 11, 2018
@creasty creasty deleted the creasty/expose_stack_trace branch September 11, 2018 02:45
@gregwebs
Copy link
Copy Markdown

@creasty I saw svc/fail. I really like what the package offers and particularly the idea of being able to merge stack traces. However, I am concerned about the potential for worse performance with all the stack trace creation and I am also working towards a different place in the design space by using our fork of pkg/errors as a base and building a package for error codes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants