-
Notifications
You must be signed in to change notification settings - Fork 55
Description
Is your feature request related to a problem? Please describe.
eris.ToJSON & eris.ToString doesn't capture wrapped error stacks after joining multiple errors with standard errors.Join. Even though the data is there.
func main() {
errOne := eris.New("error one")
errTwo := eris.New("error two")
errThree := eris.Wrap(errors.Join(errTwo, errOne), "error three")
fmt.Println(eris.ToString(errThree, true))
}
// Outputs:
// error three
// main.main:/tmp/sandbox2016565250/prog.go:14
// error two
// error oneThis is because the eris.Unpack expects the the error to always be a linear chain of eris errors ending with one external error. The un-wrap loop breaks upon finding the first "external error". In the above case being described, the Error chain would be something like this: *eris.rootError -> `*errors.joinError{errs: []error{*eris.rootError, *eris.rootError}}.
Describe the solution you'd like
Update the eris.Unpack to expect multiple external errors in the chain of eris errors.
something like this:
// UnpackV2 returns a human-readable UnpackedError type for a given error.
func UnpackV2(err error) UnpackedErrorV2 {
var upErr UnpackedErrorV2
for err != nil {
switch err := err.(type) {
case *rootError:
upErr.ErrChain = append(upErr.ErrChain, ErrRoot{
Msg: err.msg,
Stack: err.stack.get(),
})
case *wrapError:
// prepend links in stack trace order
upErr.ErrChain = append(upErr.ErrChain, ErrLink{
Msg: err.msg,
Frame: err.frame.get(),
})
default:
upErr.ErrChain = append(upErr.ErrChain, ErrExternal(err))
}
err = Unwrap(err)
}
return upErr
}
type UnpackedErrorV2 struct {
ErrChain []interface{
errType() string
formatJSON() map[string]interface{}
formatStr() string
}
}Describe alternatives you've considered
I've considered following feature request, although the blast radius seems too big in that so I was trying to imagine a smaller and backward-compatible way of doing this.
Additional context