Description
Problem Statement
I have rich errors with Sentry-compatible stack traces. I use the Go standard library to Join
them:
first := NewError(...)
second := NewError(...)
joined := errors.Join(first, second)
This is a common pattern for error aggregation: it was introduced into the standard library in Go 1.20 (Feb. 2023), and GitHub indexes 53.2k public instances.
I'd like to capture joined
with the Sentry SDK and retain both errors — with their individual stack traces — on the resulting Sentry event.
Today, CaptureException
yields an event with a single Exception
(representing joined
), with no stack trace information associated with it.
Solution Brainstorm: (Draft PR)
This SDK plays nice with errors.Wrap
(see #792) and (github.com/pkg/errors).Wrap
. It can introduce analogous support for errors.Join
.
Compose | Decompose |
---|---|
errors.Wrap |
errors.Unwrap |
(github.com/pkg/errors).Wrap |
interface{ Cause() error } (source) |
✨ errors.Join |
interface{ Unwrap() []error } (docs) |
Implementation
Two relevant excerpts from the standard library errors docs:
A non-nil error returned by
Join
implements theUnwrap() []error
method.
It is invalid for an
Unwrap
method to return an[]error
containing anil
error value.
This represents a major change in the data model for error
composition: wrapped errors form a clear causal chain, whereas joined errors are a tree that can contain chains of wrapped errors. Rather than looping linearly over the causal chain, SetException
has to
- traverse a tree of decomposed errors
- handle more complex parent/child relationships — a "child" (composed
error
) can have several parents (first
andsecond
in the example above)
The draft diff linked above implements depth-first traversal of the error tree in a new errorTree
type. It passes the SetException
unit tests, plus additional cases including joined errors.
Open questions
- Does Sentry's treatment of exceptions support multi-parental relationships/trees of exceptions?
- Accordingly, how should joined errors be represented as
[]sentry.Exception
s?
- Accordingly, how should joined errors be represented as
- How should
maxExceptionDepth
translate to a tree data model?
Metadata
Metadata
Assignees
Labels
Type
Projects
Status