Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xerrors: allow accessing the frame for each error directly #30038

Open
nhooyr opened this issue Jan 31, 2019 · 8 comments
Open

xerrors: allow accessing the frame for each error directly #30038

nhooyr opened this issue Jan 31, 2019 · 8 comments
Labels
Milestone

Comments

@nhooyr
Copy link
Contributor

@nhooyr nhooyr commented Jan 31, 2019

When using structured logging with errors, we don't want a string representation of the error + the frame, we want to access the error string, function name and file:line separately to make them separate fields in the UI and to make it easier to analyze logs. For now, I've written an xerrors.printer that just stores all lines that are printed to it and then returns those and based on xerrors atm, the first line is the error message, second is the function and third is the file name. But this is janky and fragile.

An easy way to do this is to add an interface to the package that errors can implement to return their frames.

@rsc
Copy link
Contributor

@rsc rsc commented Feb 1, 2019

Right now we don't want to expose the internal representation and commit to one particular implementation. Maybe later, once we have more experience with all of this.

@andybons andybons added this to the Unreleased milestone Feb 4, 2019
@andybons
Copy link
Member

@andybons andybons commented Feb 4, 2019

@rsc where does this leave the issue? Did you mean to keep it open?

@nhooyr

This comment has been hidden.

@nhooyr

This comment has been hidden.

@jszwedko
Copy link
Contributor

@jszwedko jszwedko commented May 3, 2019

@nhooyr I was just about to write the same string parsing code to handle this. Would you mind sharing yours?

Our use case is sending the stack trace as structured metadata to Sentry.

@jszwedko
Copy link
Contributor

@jszwedko jszwedko commented May 3, 2019

In case anyone stumbles upon this issue. I came up with the following, fragile, implementation:

type frame struct {
	Error    string
	File     string
	Line     string
	Function string
}

type errorPrinter []*frame

// Handle printing of message
// https://github.com/golang/xerrors/blob/1f06c39b43733b74392b1972507822714ced3242/errors.go#L30
func (e *errorPrinter) Print(args ...interface{}) {
	*e = append(*e, &frame{Error: fmt.Sprintf("%s", args[0])})
}

// Handle printing of stack frame
// https://github.com/golang/xerrors/blob/1f06c39b43733b74392b1972507822714ced3242/frame_go1_12.go#L48
func (e *errorPrinter) Printf(format string, args ...interface{}) {
	currentFrame := (*e)[len(*e)-1]
	switch format {
	case "%s\n    ":
		currentFrame.Function = fmt.Sprintf("%s", args[0])
	case "%s:%d\n":
		currentFrame.File = fmt.Sprintf("%s", args[0])
		currentFrame.Line = fmt.Sprintf("%d", args[1])
	}
}

func (e *errorPrinter) Detail() bool {
	return true
}

I included a test in my code to catch changes to the formatting.

@v0id3r
Copy link

@v0id3r v0id3r commented Jun 19, 2019

I also faced this problem trying to send my errors to Rollbar. It looks for interface, to build trace chain:

type CauseStacker interface {
	error
	Cause() error
	Stack() []runtime.Frame
}

Sadly - it seems to be possible only with custom errors.
But what if xerrors can give us runtime.Frame and some corresponding interface (like we already have Wrapper)?

@nhooyr
Copy link
Contributor Author

@nhooyr nhooyr commented Jun 17, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.