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

Wrong explanation about the Exception Interface in docs. #8871

Closed
3 tasks done
bhargavcp opened this issue Aug 28, 2023 · 6 comments
Closed
3 tasks done

Wrong explanation about the Exception Interface in docs. #8871

bhargavcp opened this issue Aug 28, 2023 · 6 comments

Comments

@bhargavcp
Copy link

Is there an existing issue for this?

How do you use Sentry?

Self-hosted/on-premise

Which SDK are you using?

@sentry/browser

SDK Version

7.57.0

Framework Version

7.57.0

Link to Sentry event

No response

SDK Setup

Sentry.init({
    dsn: <redacted>,
    integrations: integrations,
    release: `${$BUILD_FLAVOR}-${$REVISION}`,
    environment: $BUILD_FLAVOR,
    transport: (transportOptions: BrowserTransportOptions) =>
      makeFetchTransport(transportOptions, fetchImpl),
    maxBreadcrumbs: 100,
    sendClientReports: false,
    beforeSend: (event: Event, hint?: EventHint) => {
     <redacted>
     /**
      * Essentially, here if the event.exception.values[0] is of the type that we want to skip, we return null, 
      * otherwise we just return the event.
      */
    },
  });

Steps to Reproduce

Throw an error from a function (let's call it MessageRenderer) that returns React components based on certain conditions, and in one of the conditions it throws an error.
The return of this function is wrapped in sentry react's ErrorBoundary component.

Expected Result

When looking at the exception.values list in the event object in the beforeSend function, based on the docs (link: https://develop.sentry.dev/sdk/event-payloads/exception/), I was expecting the original error thrown from the function (MessageRenderer from my example above) to be present in the first index, followed by the ErrorBoundary error.

Actual Result

But, the first index (index 0) is taken up by the React ErrorBoundary Error object and the second index (index 1) contains the original thrown error. This is opposite of what is mentioned in the docs.

Am I missing something or is Error Boundary a unique case where this is not true?

@Lms24
Copy link
Member

Lms24 commented Aug 28, 2023

Hi @bhargavcp just to confirm, you're using @sentry/react, correct?
Also, did you set up our ErrorBoundary as described here?

Since you're on self-hosted Sentry, would you mind sharing a (minimal) JSON of the event you're describing?

Afaict, we set the original error (sticking with your example, from MessageRenderer) as cause for the React error boundary error. Another integration of ours, LinkedErrors will take care of correctly adding the cause (i.e. the original error) to the array of errors in exception.values. Maybe there's indeed a problem with ordering.

Gonna tag @AbhiPrasad as you have the most context around the error boundary - do you think we need to adjust something here?

@AbhiPrasad
Copy link
Member

The ordering here is on purpose. Please see #7557 (comment) for more details.

@bhargavcp
Copy link
Author

bhargavcp commented Aug 28, 2023

@AbhiPrasad @Lms24 thank you for the reply. I'm just wondering, does this ordering apply for all types of chained exceptions or is React Error Boundary a special case?

So in the Python snippet from the docs

try:
    raise Exception
except Exception as e:
    raise ValueError from e

should the order of error values be [ValueError from e, Exception]? i.e. reverse of what is mentioned in the docs?

@Lms24 yes we're using @sentry/react and it is set up as mentioned in the doc you linked. Here's what the exception.values array looks like.

{
    "values": [
        {
            "type": "React ErrorBoundary Error",
            "value": "nonParticipantBotResponse",
            "stacktrace": {
                "frames": [....]
            },
            "mechanism": {
                "type": "chained",
                "handled": true,
                "source": "cause",
                "exception_id": 1,
                "parent_id": 0
            }
        },
        {
            "type": "UnsupportedMessageError",
            "value": "nonParticipantBotResponse",
            "stacktrace": {
                "frames": [....]
            },
            "mechanism": {
                "type": "generic",
                "handled": true,
                "is_exception_group": true,
                "exception_id": 0
            }
        }
    ]
}

@AbhiPrasad
Copy link
Member

does this ordering apply for all types of chained exceptions or is React Error Boundary a special case

The react error boundary is a special case and is inconsistent on purpose. If the quality of the error produced react gets higher in a future version of react we'll re-adjust this to make it consistent with everything else.

@bhargavcp
Copy link
Author

The react error boundary is a special case and is inconsistent on purpose.

Thanks @AbhiPrasad , which means that the Python example in the doc is correct and we can expect non-React boundary errors to behave as mentioned in the docs?

@AbhiPrasad
Copy link
Member

which means that the Python example in the doc is correct and we can expect non-React boundary errors to behave as mentioned in the docs

yes you should expect the other errors to behave as documented. If they don't please let us know and we'll fix asap!

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

No branches or pull requests

3 participants