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

[React 19] Allow access of default error callbacks in onCaughtError and onUncaughtError #29581

Closed
AbhiPrasad opened this issue May 24, 2024 · 2 comments
Labels

Comments

@AbhiPrasad
Copy link

AbhiPrasad commented May 24, 2024

Hey React team! We at Sentry have been working on adding support for the new onCaughtError and onUncaughtError root options in React 19 for error reporting.

Here's a PR I'm iterating on atm: getsentry/sentry-javascript#12147

The API we are looking to add looks something like so:

import { reactErrorHandler } from '@sentry/react';
import { hydrateRoot } from "react-dom/client";

ReactDOM.hydrateRoot(
  document.getElementById("root") as HTMLElement,
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  {
    onUncaughtError: reactErrorHandler(),
    onCaughtError: reactErrorHandler((error, errorInfo) => {
      // optional callback if users want more/custom config in addition?
    }),
  }
);

The only issue with Sentry.reactErrorHandler in the current form is that setting the onUncaughtError or onCaughtError options overrides the defaults for onUncaughtError and onCaughtError, which means you lose out on the dev mode logging like so:

if (__DEV__) {
const componentStack =
errorInfo.componentStack != null ? errorInfo.componentStack : '';
const componentNameMessage = componentName
? `An error occurred in the <${componentName}> component:`
: 'An error occurred in one of your React components:';
console['warn'](
'%s\n%s\n\n%s',
componentNameMessage,
componentStack || '',
'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
'Visit https://react.dev/link/error-boundaries to learn more about error boundaries.',
);
}

In this case there is no way for us to replicate the An error occurred in the <${componentName}> component: message (because componentName is private API), so asking users to add Sentry.reactErrorHandler degrades their local development experience.

This means if someone adds Sentry, or their own error logging via these hooks, they lose out on useful messaging in dev mode. We could recommend to users to make this production-only, but folks also use Sentry error reporting locally via Spotlight, Sentry for development.

Is there a way we can get access to the original onCaughtError or onUncaughtError handler so we can execute that, while sending the error to Sentry at the same time? Or is there are alternate way we can design this API to make that happen?

Thanks!

@rickhanlonii
Copy link
Member

Yeah, we're actually probably going to remove the componentName from the default. It's often wrong, and doesn't account for ignored frames. What you really want, is to traverse the component stack, filtering out any ignored frames (which the app has full visibility into, but React does not). So the recommendation is to show the error + the component stack (with the filtering when available), and not have it in the message at all.

After removing it, the behavior will be the same, so there's no need to call the defaults.

@AbhiPrasad
Copy link
Author

Music to my ears - gonna proceed with my implementation then. Thank you @rickhanlonii!

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

No branches or pull requests

2 participants