feat(react): Add Sentry.reactErrorHandler#12147
Merged
AbhiPrasad merged 11 commits intodevelopfrom May 27, 2024
Merged
Conversation
3cdc306 to
7741886
Compare
Contributor
size-limit report 📦
|
Closed
mydea
reviewed
May 22, 2024
packages/react/README.md
Outdated
| const root = createRoot(container, { | ||
| // Callback called when an error is thrown and not caught by an Error Boundary. | ||
| onUncaughtError: (error, errorInfo) => { | ||
| Sentry.captureReactException(error, errorInfo); |
Member
There was a problem hiding this comment.
I would vote for a different name here - imho this is a bit misleading, like I could easily see users just using this instead of captureException() 🤔
What if instead we'd do something like this:
const root = createRoot(container, {
// Callback called when an error is thrown and not caught by an Error Boundary.
onUncaughtError: Sentry.reactErrorHandler(),
onCaughtError: Sentry.reactErrorHandler((error, errorInfo) => {
// optional callback if users want more/custom config in addition?
})
});
Contributor
Author
There was a problem hiding this comment.
I like Sentry.reactErrorHandler a lot better - will change!
Contributor
Author
There was a problem hiding this comment.
I have some concerns with my initial approach that also applies to Sentry.reactErrorHandler. #11798 (comment)
Pinged react team member on this, let's see if we can get feedback.
andreiborza
approved these changes
May 22, 2024
packages/react/src/error.ts
Outdated
| * Recurse through `error.cause` chain to set cause on an error. | ||
| */ | ||
| export function setCause(error: Error & { cause?: Error }, cause: Error): void { | ||
| const seenErrors = new WeakMap<Error, boolean>(); |
Member
There was a problem hiding this comment.
l: could use a WeakSet here instead, wdyt?
This was referenced May 24, 2024
Closed
AbhiPrasad
added a commit
that referenced
this pull request
May 24, 2024
Sentry.reactErrorHandler
cf24410 to
2550dac
Compare
0ba4bcd to
c306b49
Compare
15d3d2d to
9224b63
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ref #11798
React 19 brings some improvements to error handling with https://react.dev/blog/2024/04/25/react-19#error-handling! This PR exposes a new method,
Sentry.reactErrorHandlerthat helps users interact with these new React 19 error handling hooks.Background
React Error handling originally relied only on error boundaries, React components that would automatically catch component rendering errors and display fallback UIs.
We added support for this by exporting our own
ErrorBoundarycomponent.If you notice above, the
infoparameter passed intocomponentDidCatchhas acomponentStackproperty.componentStackis a synthetic stacktrace that represents the component call-chain that threw the error. Fortunately because this is a synthetic stacktrace, we can parse it as an error in the SDK and attach it to the original exception as a linked exception viaerror.cause.Important to note: If a component chain is not wrapped in an error boundary though, we do not get access to the
componentStack, as the error bubbles up to the global error handler.React 19
In React 19 they've two new options,
onCaughtErrorandonUncaughtErrorto the React DOM public API.onCaughtErroris a callback called when React catches an error in an Error Boundary. This effectively works just like having anErrorBoundarywithcomponentDidCatch.onUncaughtErroris a callback called when an error is thrown and not caught by an Error Boundary. This means we can addcomponentStackinformation to these errors without requiring users to add error boundaries everywhere (useful for 3rd party component libraries and similar).Given
onCaughtError,onUncaughtErrorandcomponentDidCatchall have identical APIsThis PR introduces
Sentry.reactErrorHandler, which looks like so:To validate this change, we add a react 19 e2e test.
Next Steps
After we merge this in and update the docs, we can explore automatically instrumenting
createRootfromreact-domto addSentry.reactErrorHandleraccordingly, but that is a next step.