pkg / errors

Simple error handling primitives

Home Page:https://godoc.org/github.com/pkg/errors

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Proposal: add a package-level StackTrace() method

flimzy opened this issue · comments

I think it would be convenient to have a package-level StackTrace(err error) StackTrace method, as a bit of an analog to the Cause(err error) error method, which returns the earliest stack trace found in the composite error value.

This is something I have implemented in at least three packages myself now, but it seems likely to be of value to others, so I'm beginning to think perhaps it belongs here.

The reason it's not sufficient to simply call err.StackTrace(), is that an error may have been Wrap()ed multiple times, in which case one generally (if not always) wants the earliest stack trace. And:

cause := err.(causer)
stackTrace := cause.(stackTracer)

doesn't work, because generally the cause does not include a stack trace.

So my proposal is to add a package-level StackTrace() method such that one can do, for instance:

if stackTrace := errors.StackTrace(err); stackTrace != nil {
    fmt.Printf("Stacktrace: %+v\n", stackTrace)
}

If this proposal meets general approval, I can quickly submit a PR for further consideration.

I see the utility of this function, but like other similar requests for
wrapping errors if they haven't already been wrapped etc, or only wrapping
if haven't been annotated in a particular I'm wary because the logic is
subtle and the result of errors.StackTrace(err) would work for you, but I'm
sure someone else would want a single different version.

That's a fair criticism. Thanks for considering.

Don't worry; I didn't mean it in the negative sense, and I don't take it personally. I do prefer a lean library, too. And it's quite true that someone may not always want just a single stack trace, or the same stack trace I find interesting. These are things made more apparent as I read other open issues, after having written my proposal earlier today.

I think your caution (and that of the Go project in general) is well warranted, and wise.

If you feel there's value in leaving it open, please feel free to re-open it.

For my part, the implementation is already done in the packages where my team needs it, so I'm willing to consider the case closed.

I'd appreciate a collection of add-or "recipes" like this one—things that can be layered on top of the core package, and hence don't need to be part of it, but that will likely be useful to many people. I don't think Dave wants a contrib directory here. Perhaps some gists to which we can link?