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 · 7 comments

Comments

@nhooyr
Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Member

commented Feb 4, 2019

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

@nhooyr

This comment was marked as resolved.

Copy link
Contributor Author

commented Feb 4, 2019

@andybons it is open.

@nhooyr

This comment was marked as resolved.

Copy link
Contributor Author

commented Feb 4, 2019

Ah I see, you're wondering whether he wants to close it.

@jszwedko

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

Copy link

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)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.