Skip to content

The ExtraErrorData integration is not capturing nested error causes #15142

Closed

Description

@michaelschufi

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/nextjs

SDK Version

8.51.0

Framework Version

Next 15.1.3

Link to Sentry event

https://sally-and-friends.sentry.io/issues/6215894150/events/2b86efb54ff54674bac3bd0582bc1952/

Reproduction Example/SDK Setup

// sentry.server.config (same for the other two)

Sentry.init({
  integrations: [
    Sentry.extraErrorDataIntegration({
      depth: 15,
    }),
  ],
  normalizeDepth: 15,
});

// my custom error class' toJSON

export class CustomError extends Error {
  // ... tell me if you need the whole class. But the point is, that this.cause is returned inside `toJSON`

  toJSON(): Record<string, unknown> {
    return {
      message: this.message,
      name: this.name,
      cause: this.cause,
    };
  }
}

Steps to Reproduce

  1. Set up a custom error class that has a toJSON method, which includes the this.cause property.
  2. Throw an error which has such error in its cause. E.g.
    throw new TRPCError("Top-level error", {
      cause: new CustomError("Nested error", {
        foo: "bar"
      })
    })

Expected Result

The top-level error is getting serialized, including the extra error data.
The cause field is another structured error data. E.g.

{
  message: "Nested error",
  name: "Custom Error",
  cause: {foo: "bar"},
}

because capturing the cause is enabled by default.

Actual Result

The nested error getting serialized in the format `${errorClassName}: ${message} instead of the whole structured data.

Image

Activity

  1. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Jan 23, 2025
  2. andreiborza commented on Jan 23, 2025

    @andreiborza
    Member

    Hi @michaelschufi, thanks for filing this.

    I just tested this out and had a look at our code, indeed if cause is an Error or if a value of a property inside the JSON returned from toJSON is an Error it gets immediately serialized via toString regardless of having a toJSON itself.

    This is something we can consider changing, I'll bring it up with the team. Otherwise, we also welcome contributions if you're interested.

  3. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Jan 23, 2025
  4. michaelschufi commented on Jan 24, 2025

    @michaelschufi
    Author

    Thanks for the quick response @andreiborza. Sounds good!

    I fully expected the integration to walk through all the attributes up to the defined depth - and with captureErrorCause enabled, including the causes of all errors also being serialized.

    Also, I want to mention that sometimes there's an error in the error stack that we have no control over (e.g. from a framework TRPCError for example). This error still might have an attribute like originalError or cause, letting us access our CustomError that holds important information about the context the exception occurred. But it does not have a toJSON method. It would be great if attributes of such errors, most importantly the cause, still can get walked through to actually reach the error with the most important context.

    Edit: Regarding contributions - I'm not sure how, but I'm happy to assist.

  5. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Jan 24, 2025
  6. andreiborza commented on Jan 24, 2025

    @andreiborza
    Member

    Thanks, we'll take a look at that too.

  7. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Jan 24, 2025
  8. andreiborza commented on Feb 6, 2025

    @andreiborza
    Member

    @michaelschufi just a heads up, this is very low prio for us atm. I put it in the backlog but we might not get around to it in a while. We don't even have a good idea of how this should work tbh.

  9. removed theissue type on Mar 4, 2025
  10. 3 remaining items

  11. IgnusG commented on May 5, 2025

    @IgnusG

    We are also interested in this setup. Our stack uses nested errors such as:

    Error: fetching X failed    <-- this error has no toJSON
        at ...
    Caused by: RequestError: Failed to fetch: X    <-- this error has additional information about why the request failed
        at ...
    Caused by: TypeError: Failed to fetch
        at FetchClient.fetch
    

    In this case we would like to add a toJSON to our RequestError to attach additional information around what the response (if any) was, what the status code was etc.

    We don't know how deep our RequestError will be in the cause structure (it could be top level, it could be 3 levels deep), which makes this difficult to work around.

    Right now if it's not top level, the integration doesn't call the toJSON method loosing this information. This leads us to debug issues such as Request X failed with status code 500 and no other information around what else the server might've returned.

    For now I was thinking of building a small integration myself that could deal with this and create a nested structure for this extra data by inspecting the errors within the cause chain and calling toJSON on every level.

  12. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on May 5, 2025
  13. lforst commented on May 5, 2025

    @lforst
    Contributor

    I think building your own eventProcessor (addable via Sentry.addEventProcessor((...) => {...})) is a reasonable approach to unblock yourself until we get to this.

  14. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on May 5, 2025
  15. added a commit that references this issue on Aug 12, 2025
    a89aa3d
  16. github-actions commented on Aug 12, 2025

    @github-actions
    Contributor

    A PR closing this issue has just been released 🚀

    This issue was referenced by PR #17375, which was included in the 10.5.0 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions