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

Make hydration errors more actionable #26224

Closed
AbhiPrasad opened this issue Feb 23, 2023 · 21 comments
Closed

Make hydration errors more actionable #26224

AbhiPrasad opened this issue Feb 23, 2023 · 21 comments
Labels
Resolution: Stale Automatically closed due to inactivity

Comments

@AbhiPrasad
Copy link

AbhiPrasad commented Feb 23, 2023

Hey folks! We at Sentry build error/performance monitoring SDKs and wanted to reach out to see if we could improve the state of hydration errors and make them more actionable. Specifically, we want to look at the stacktraces of hydration errors when you are using production react bundles.

Since React 18 has been getting more adoption, many of our users using React SSR apps have been getting flooded with hydration errors, like listed below:

'https://reactjs.org/docs/error-decoder.html?invariant=422', // There was an error while hydrating this Suspense boundary. Switched to client rendering.
'https://reactjs.org/docs/error-decoder.html?invariant=423', // There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root...
'https://reactjs.org/docs/error-decoder.html?invariant=425'  // Text content does not match server-rendered HTML...

When we discussed this with the community, many users simply wanted to just filter these errors because they were not actionable.

Looking at the implementation in the codebase a simple string error is thrown:

and because of how it is generated the stack trace is often not detailed enough to give users insights about what components/functions were problematic.

For example, here's a stacktrace I generated from a stock Next.js application with one of these hydration errors:

https://sentry-test.sentry.io/share/issue/b70ea591bbfc4728b33da495148ac9cd/

image

Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
  at Vk(./node_modules/react-dom/cjs/react-dom.production.min.js:280:383)
  at 4448/oF/<(./node_modules/react-dom/cjs/react-dom.production.min.js:280:319)
  at Jk(./node_modules/react-dom/cjs/react-dom.production.min.js:280:319)
  at Ok(./node_modules/react-dom/cjs/react-dom.production.min.js:271:86)
  at Hk(./node_modules/react-dom/cjs/react-dom.production.min.js:268:399)
  at J(./node_modules/scheduler/cjs/scheduler.production.min.js:13:197)
  at R(./node_modules/scheduler/cjs/scheduler.production.min.js:14:126)

As you can see the frames all come from react-dom internals, which means users have no way to start investigating where to look beyond the URL of the page.

In the end we've decided to filter these out from default from sentry: getsentry/sentry#45038, but we recognize this is not an ideal solution. Hydration errors are things people should fix, and we want to make it easier for people to fix them!

So with that in mind, are there ways we could make this easier for users? Could we attach a componentStack like we do with error boundaries for these errors? Could we point users to the element that was causing this issue? Any and all ideas/feeback greatly appreciated.

@AbhiPrasad
Copy link
Author

AbhiPrasad commented Feb 23, 2023

Seems like Next.js 13.2 has improved their error overlays and local debugging experience for these - #24519 (comment)

vercel/next.js#45089 seems to be this PR

Edit: These are dev only - which still means the production stacktraces still have the same problem - which is what we are looking to improve here.

@gaearon
Copy link
Collaborator

gaearon commented Feb 24, 2023

Thanks for reaching out.

So with that in mind, are there ways we could make this easier for users? Could we attach a componentStack like we do with error boundaries for these errors? Could we point users to the element that was causing this issue? Any and all ideas/feeback greatly appreciated.

I believe you should be receiving those in the onRecoverableError callback for hydrateRoot as the second argument. I think on main we might also be patching it onto the error object (not sure, would need to check).

Is that helpful? Should we be doing more?

@AbhiPrasad
Copy link
Author

AbhiPrasad commented Feb 24, 2023

Appreciate the quick response!

I believe you should be receiving those in the onRecoverableError callback for hydrateRoot as the second argument

So this works pretty decently to a certain extent, we just have to convince framework authors to expose these hooks more easily, as it's better than nothing.

For 425 and 418, we get componentStacks:

a
div
i
u@http://0.0.0.0:3000/_next/static/chunks/main-705a528c766ed2ff.js:1:33240
401/t.PathnameContextProviderAdapter@http://0.0.0.0:3000/_next/static/chunks/main-705a528c766ed2ff.js:1:42849
G@http://0.0.0.0:3000/_next/static/chunks/main-705a528c766ed2ff.js:1:7595
Y@http://0.0.0.0:3000/_next/static/chunks/main-705a528c766ed2ff.js:1:9134
ea@http://0.0.0.0:3000/_next/static/chunks/main-705a528c766ed2ff.js:1:11907

So here a, div, and i are react components, which should help a lot with debugging. The only issue is that they don't have function names/line and col numbers - so we can't apply sourcemaps to transform these into readable component names. Of course people can set a displayName, but that's not realistic for a bigger application.

Here's some basic boilerplate that will work to send this stuff to an error monitoring service:

function onRecoverableError(error, errInfo) {
 let context = {};

  if (errInfo && errInfo.componentStack) {
     // generating this synthetic error allows services like Sentry to apply sourcemaps
     // to unminify the stacktrace and make it readable.
     const errorBoundaryError = new Error(error.message);
     errorBoundaryError.name = `React ErrorBoundary ${errorBoundaryError.name}`;
     errorBoundaryError.stack = errorInfo.componentStack;

     // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
     error.cause = errorBoundaryError

     // you can also just add the plain text as some kind of added event context
     context.react = {
       componentStack: errorInfo.componentStack
     }
  }
 // feel free to replace with your favourite error monitoring service
 Sentry.captureException(error, { context })
}

It seems like 423 does not generate a componentStack though. Given though that the other invariants are always thrown with this, I think it's fine.

So with that in mind two immediate items:

  1. We have to convince framework authors to expose onRecoverableError.

Seems like this has been a feature request in Next.js, and it seems Astro can also improve here. Remix thankfully seems to be super transparent with exposing hydrateRoot. Gatsby also allows for this. We at Sentry can help talk to these folks!

  1. We need better frames for the react components in the componentStack.

Without proper frames, we can never apply sourcemaps, so users are stuck with minified component names.

As for anything else, I'm trying to brainstorm what other tools we can give to people to help identify what to fix here. Ideally most folks just want the line of code that they need to change.

If bundle size is a concern from adding new logic, perhaps we can add an API that returns a errored response to the server that CSR had to occur. Then the server could report many details about what kind of HTML it tried to serve, and as along as you can trace the error somehow between backend/frontend, you might be able to debug this faster.

@gaearon
Copy link
Collaborator

gaearon commented Feb 24, 2023

So here a, div, and i are react components, which should help a lot with debugging. The only issue is that they don't have function names/line and col numbers - so we can't apply sourcemaps to transform these into readable component names.

Aren't these built-in ones like <a> etc? You should be able to map the actual React components further in the stack. Yes, this wouldn't tell the exact location, but would at least narrow it down to the component function.

we just have to convince framework authors to expose these hooks more easily, as it's better than nothing.

Or maybe we should patch it onto the object. We already patch err.digest on main. I'll ask if we considered doing the same for .componentStack and why (not).

Here's some basic boilerplate that will work to send this stuff to an error monitoring service:

Fair, this could work too.

It seems like 423 does not generate a componentStack though. Given though that the other invariants are always thrown with this, I think it's fine.

Can you provide a repro case? I could have a look.

Without proper frames, we can never apply sourcemaps, so users are stuck with minified component names.

It's not obvious to me why the frames in the stack you mentioned aren't proper. They are reconstructed from actual stack lines merged together so they should give you React component functions. The only missing parts are components like <div>. What am I missing?

@lforst
Copy link

lforst commented Feb 28, 2023

Or maybe we should patch it onto the object. We already patch err.digest on main. I'll ask if we considered doing the same for .componentStack and why (not).

Having componentStack as a property on hydration errors would be really cool and useful.

Even though it would also be cool to have file/lineno/col for individual tags I don't think it is absolutely necessary - without it the component stack is already useful enough. Implementing this would probably mean having to patch the stack trace together somehow using synthetic errors which is probably quite expensive.

@AbhiPrasad
Copy link
Author

@gaearon apologize for the delay, had gone on vacation last week!

made a quick example to help address some of the points you made: https://github.com/AbhiPrasad/nextjs-hydration-error-example using a nextjs app.

I had to monkeypatch onRecoverableError since next does not expose this, so please excuse that part of the code 😅.

Aren't these built-in ones like etc? You should be able to map the actual React components further in the stack. Yes, this wouldn't tell the exact location, but would at least narrow it down to the component function.

You're right that they mostly help. We generally get a componentStack like so in prod builds:

div
main
p
i@http://localhost:3000/_next/static/chunks/pages/_app-53818a55c8835939.js:14:12349
6985/t.PathnameContextProviderAdapter@http://localhost:3000/_next/static/chunks/main-b1241a9a70bb7dcd.js:1:42869
G@http://localhost:3000/_next/static/chunks/main-b1241a9a70bb7dcd.js:1:7600
Y@http://localhost:3000/_next/static/chunks/main-b1241a9a70bb7dcd.js:1:9138
ea@http://localhost:3000/_next/static/chunks/main-b1241a9a70bb7dcd.js:1:11913

This + the URL of the page is usually good enough to figure out where the issue is. The problem is they aren't solely the built-in components all the time, so we get minified React component names in there for more complex use cases, which is still pretty confusing for users.

p
div
m // minified name
div
f // minified name
div
h // minified name
main
p
i@http://localhost:3000/_next/static/chunks/pages/_app-53818a55c8835939.js:14:12349
6985/t.PathnameContextProviderAdapter@http://localhost:3000/_next/static/chunks/main-b1241a9a70bb7dcd.js:1:42869
G@http://localhost:3000/_next/static/chunks/main-b1241a9a70bb7dcd.js:1:7600
Y@http://localhost:3000/_next/static/chunks/main-b1241a9a70bb7dcd.js:1:9138
ea@http://localhost:3000/_next/static/chunks/main-b1241a9a70bb7dcd.js:1:11913

Or maybe we should patch it onto the object. We already patch err.digest on main. I'll ask if we considered doing the same for .componentStack and why (not).

This would be great!

Can you provide a repro case? I could have a look.

When running https://github.com/AbhiPrasad/nextjs-hydration-error-example in production mode, invariant 423 does not generate a componentStack (message: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.)

console.log(error);
console.log(errorInfo);
console.log(errorInfo.componentStack);

image

It's not obvious to me why the frames in the stack you mentioned aren't proper. They are reconstructed from actual stack lines merged together so they should give you React component functions. The only missing parts are components like

. What am I missing?

This is partly a Sentry consequence, since we need the filename and line/col number to do source mapping, which helps with the case where there are minified component names in the stacktrace. Something like G@http://localhost:3000/_next/static/chunks/main-b1241a9a70bb7dcd.js:1:7600 for example.

But we can live without this for now!

Finally, when you generate a hydration issue, you get 3 errors thrown:

  1. 425: Text content does not match server-rendered HTML.
  2. 418: Hydration failed because the initial UI does not match what was rendered on the server.
  3. 423: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.

I understand why all of these errors must be thrown (they all signal different parts of the problem), but IMO the experience of getting all of these in the console/in your production error monitoring system is confusing and can be overwhelming for users, especially those on the more junior side. Perhaps we can think of a way of reducing the amount of errors thrown?

@eps1lon
Copy link
Collaborator

eps1lon commented Mar 9, 2023

Should we reduce the errors or describe better how to treat these?

Something in the direction of

-Text content does not match server-rendered HTML.
+Hydration error: Text content does not match server-rendered HTML.

- Hydration failed because the initial UI does not match what was rendered on the server.
+ Hydration failed because the initial UI does not match what was rendered on the server. To fix this error, fix all the hydration errors above.

423 helps understand the impact. Though it would be nice to understand if 423 implies 418 or 418 implies 423 and what value there is in having these separated. For 425 I understand because we might have multiple 425 but just one 418 if I understood these correctly.

@AbhiPrasad
Copy link
Author

I feel like the better description is a great first step - especially because it clearly shows how the errors are related together.

423 helps understand the impact

Agree here - though it would also be nice to somehow get an idea of the potential consequence of this error. Maybe this is something that Sentry or other performance monitoring tools can help with (show how LCP suffered because 423 fired on a page).

A cool idea I had mulling around was that when react does it's client-side re-render, we attach the elementtiming attribute somehow to the client-side rendered elements somehow.

Though it would be nice to understand if 423 implies 418 or 418 implies 423 and what value there is in having these separated. For 425 I understand because we might have multiple 425 but just one 418 if I understood these correctly

Yes, you might have multiple instances of 425, which I think should make sense to the average developer. Getting the componentStack directly on the error obj should also help even more here.

@johnnyreilly
Copy link

johnnyreilly commented Oct 10, 2023

Heya!

I happened on this whilst helping @slorber look into a hydration issue that has surfaced as Docusaurus migrates to React 18:

facebook/docusaurus#9379 (comment)

We tried plugging in the errorInfo logging in place we got this:

image

main.78700692.js:2 Docusaurus React Root onRecoverableError: Error: Minified React error #418; visit https://reactjs.org/docs/error-decoder.html?invariant=418 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at ls (main.78700692.js:2:109705)
    at Oc (main.78700692.js:2:182751)
    at xd (main.78700692.js:2:170225)
    at vd (main.78700692.js:2:170197)
    at sd (main.78700692.js:2:165247)
    at w (main.78700692.js:2:232540)
    at MessagePort.T (main.78700692.js:2:233072) {componentStack: '\n    at div\n    at G (http://localhost:3000/assets…calhost:3000/assets/js/main.78700692.js:2:199606)', digest: null}
n @ main.78700692.js:2
(anonymous) @ main.78700692.js:2
wd @ main.78700692.js:2
sd @ main.78700692.js:2
w @ main.78700692.js:2
T @ main.78700692.js:2
main.78700692.js:2 Docusaurus React Root onRecoverableError: Error: Minified React error #418; visit https://reactjs.org/docs/error-decoder.html?invariant=418 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at ls (main.78700692.js:2:109705)
    at Oc (main.78700692.js:2:182751)
    at xd (main.78700692.js:2:170225)
    at vd (main.78700692.js:2:170197)
    at sd (main.78700692.js:2:165247)
    at w (main.78700692.js:2:232540)
    at MessagePort.T (main.78700692.js:2:233072) {componentStack: '\n    at div\n    at q (http://localhost:3000/assets…calhost:3000/assets/js/main.78700692.js:2:199606)', digest: null}
n @ main.78700692.js:2
(anonymous) @ main.78700692.js:2
wd @ main.78700692.js:2
sd @ main.78700692.js:2
w @ main.78700692.js:2
T @ main.78700692.js:2
main.78700692.js:2 Docusaurus React Root onRecoverableError: Error: Minified React error #418; visit https://reactjs.org/docs/error-decoder.html?invariant=418 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at ls (main.78700692.js:2:109705)
    at Oc (main.78700692.js:2:182751)
    at xd (main.78700692.js:2:170225)
    at vd (main.78700692.js:2:170197)
    at sd (main.78700692.js:2:165247)
    at w (main.78700692.js:2:232540)
    at MessagePort.T (main.78700692.js:2:233072) {componentStack: '\n    at footer\n    at kn (http://localhost:3000/as…calhost:3000/assets/js/main.78700692.js:2:199606)', digest: null}
n @ main.78700692.js:2
(anonymous) @ main.78700692.js:2
wd @ main.78700692.js:2
sd @ main.78700692.js:2
w @ main.78700692.js:2
T @ main.78700692.js:2
main.78700692.js:2 Docusaurus React Root onRecoverableError: Error: Minified React error #423; visit https://reactjs.org/docs/error-decoder.html?invariant=423 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at Oc (main.78700692.js:2:182437)
    at xd (main.78700692.js:2:170225)
    at yd (main.78700692.js:2:170153)
    at hd (main.78700692.js:2:170016)
    at id (main.78700692.js:2:166823)
    at sd (main.78700692.js:2:165375)
    at w (main.78700692.js:2:232540)
    at MessagePort.T (main.78700692.js:2:233072) {componentStack: '', digest: null}

It's more information than we had, but it's still not very actionable. Consider the componentStack

\n    at div\n    at G (http://localhost:3000/assets/js/main.78700692.js:2:624664)\n    at Bt (http://localhost:3000/assets/js/main.78700692.js:2:661953)\n    at nav\n    at qt (http://localhost:3000/assets/js/main.78700692.js:2:663366)\n    at sn\n    at q (http://localhost:3000/assets/js/main.78700692.js:2:623699)\n    at p (http://localhost:3000/assets/js/main.78700692.js:2:264647)\n    at r (http://localhost:3000/assets/js/main.78700692.js:2:264973)\n    at http://localhost:3000/assets/js/main.78700692.js:2:672280\n    at g (http://localhost:3000/assets/js/main.78700692.js:2:275178)\n    at b (http://localhost:3000/assets/js/main.78700692.js:2:275363)\n    at y (http://localhost:3000/assets/js/main.78700692.js:2:262590)\n    at v (http://localhost:3000/assets/js/main.78700692.js:2:262676)\n    at l (http://localhost:3000/assets/js/main.78700692.js:2:277407)\n    at b (http://localhost:3000/assets/js/main.78700692.js:2:258340)\n    at f (http://localhost:3000/assets/js/main.78700692.js:2:259271)\n    at http://localhost:3000/assets/js/main.78700692.js:2:276403\n    at En (http://localhost:3000/assets/js/main.78700692.js:2:672394)\n    at Nn (http://localhost:3000/assets/js/main.78700692.js:2:673299)\n    at Ln\n    at v (http://localhost:3000/assets/js/ccc49370.aa459f07.js:1:21579)\n    at g (http://localhost:3000/assets/js/ccc49370.aa459f07.js:1:33004)\n    at g (http://localhost:3000/assets/js/main.78700692.js:2:275178)\n    at l (http://localhost:3000/assets/js/ccc49370.aa459f07.js:1:59429)\n    at h (http://localhost:3000/assets/js/ccc49370.aa459f07.js:1:33429)\n    at c (http://localhost:3000/assets/js/main.78700692.js:2:373197)\n    at n (http://localhost:3000/assets/js/main.78700692.js:2:208520)\n    at t (http://localhost:3000/assets/js/main.78700692.js:2:218284)\n    at t (http://localhost:3000/assets/js/main.78700692.js:2:219232)\n    at t (http://localhost:3000/assets/js/main.78700692.js:2:218284)\n    at M (http://localhost:3000/assets/js/main.78700692.js:2:288684)\n    at z (http://localhost:3000/assets/js/main.78700692.js:2:290015)\n    at g (http://localhost:3000/assets/js/main.78700692.js:2:285165)\n    at i (http://localhost:3000/assets/js/main.78700692.js:2:284800)\n    at p (http://localhost:3000/assets/js/main.78700692.js:2:363422)\n    at b (http://localhost:3000/assets/js/main.78700692.js:2:365297)\n    at Q (http://localhost:3000/assets/js/main.78700692.js:2:292784)\n    at t (http://localhost:3000/assets/js/main.78700692.js:2:216498)\n    at t (http://localhost:3000/assets/js/main.78700692.js:2:211808)\n    at t (http://localhost:3000/assets/js/main.78700692.js:2:199606)

It's not obvious what this reveals, beyond that a div is involved. Are there other steps we should be following to get more meaningful output perhaps?

The above was obtained by:

git clone https://github.com/facebook/docusaurus.git
cd docusaurus
yarn install
yarn build
yarn serve

Browse to http://localhost:3000/ and opening devtools to look at the console.

Interestingly (and not related to this) we've been seeing errors that only seem to surface on Ubuntu which is intriguing.

@bruno-garcia
Copy link

For folks using Replay, which has DOM snapshots, we can help you debug this with a diff:

https://changelog.getsentry.com/announcements/diff-hydration-errors-with-replay

@karlhorky
Copy link
Contributor

karlhorky commented Apr 12, 2024

Diffing for hydration errors has now been added as a feature to React in this PR by @sebmarkbage:

This has also be implemented in Next.js in the error overlay:

@AbhiPrasad does this do enough to address the wishes in this issue? Can the issue be closed now?

@AbhiPrasad
Copy link
Author

These changes only affect dev mode right? I think production hydration errors still have these same data quality issues.

Unfortunately there are a variety of environments where dev mode isn't good enough to debug this, see this twitter thread as an example.

@rickhanlonii
Copy link
Member

rickhanlonii commented Apr 26, 2024

Just noting that the hydration diff improvements have landed in the React 19 beta

These changes only affect dev mode right?

Yes, we do not log the diff in prod because it can include sensitive information. Using something like the DOM snapshot Sentry has (where you already can hide sensitive data) is a good solution for prod.

@AbhiPrasad
Copy link
Author

we do not log the diff in prod because it can include sensitive information

Could you explain more about how the diff can include sensitive information? Isn't the error being thrown with details that the client fully knows? Or is this more of a security by obscurity thing?

In general I understand the reservations though! Maybe a middle-ground is to expose an API so that users can opt-in to this behaviour if they know what they are doing (in prod bundles)? I can see the argument about how this expands the public API surface too much though.

@rickhanlonii
Copy link
Member

The client fully knows them, but the server you're reporting the logs to do not. It's also expensive to generate, so you don't want to take the perf hit in prod when it's already recoverable.

@AbhiPrasad
Copy link
Author

AbhiPrasad commented Apr 26, 2024

The client fully knows them, but the server you're reporting the logs to do not

I find this confusing because can't users send any arbitrary information to 3rd parties from the browser via a fetch call anyway? What special cases this situation for PII/sensitive information?

In the case of Sentry SDK looking at the DOM snapshot, it does scrub sensitive information client-side before sending a payload to Sentry. Couldn't the Sentry SDK (or other monitoring tools) use a similar strategy to clean up the recoverable error here?

I think generally monitoring solutions have built up the competency to be able to remove sensitive information if they are able to access the relevant data in production. There is also a big incentive for our SDKs (and the developer using them) to be able to do this well on our side because of things like GDPR, HIPAA, CCPA, etc.

It's also expensive to generate, so you don't want to take the perf hit in prod when it's already recoverable.

Yeah this is fair, but I think given hydration means you re-render anyway, isn't performance in a bad state already? Your LCP (and maybe CLS, INP) is going to suffer regardless of if you spend the time generating the error. This is where having it behind a configurable flag would be positive, then users can opt-in to this expense depending on their priorities.

I do recognize I have put in 0 work to profile/benchmark this performance-wise, so I may be making incorrect assumptions - just lmk if I'm operating with the wrong mental model! Maybe an interesting follow-up is to try running some numbers on this.

@rickhanlonii
Copy link
Member

Yeah, but if you do a fetch with data, you're opting into sending it. For error reporting, you're usually not reviewing every possible error that can emit and scrubbing private data from it. And since the error is just a string, we could change the format of the error and break your string scrubbing, and you accidentally start sending private data. So we never log the contents of state/props/innerText in errors from React.

It's not just the raw performance of generating the diffs that matters, it's also the additional code and tracking that we need to do to have the data to do the diffs. You can generate the diffs in user-land client-side when we emit the recoverable error by storing the server DOM and reading the client DOM after hydration and construct a diff to upload - and if that sounds expensive that's why we don't include it in prod haha

Couldn't the Sentry SDK (or other monitoring tools) use a similar strategy to clean up the recoverable error here?

How would you reliably do that with just a formatted string? My understanding of the way Sentry does this is with attributes, so you have structured data you can reliably omit info from.

@AbhiPrasad
Copy link
Author

Sorry for the delay, just came back from vacation!

I started iterating on a Sentry API for onRecoverableError, and some of the other React 19 error APIs: getsentry/sentry-javascript#11798.

For error reporting, you're usually not reviewing every possible error that can emit and scrubbing private data from it

Actually we do this at Sentry via PII scrubbing on our incoming exceptions. It works relatively well, but you're right that we do have to turn error strings into structured data. It's important to note though that we have prior work on this, Error.prototype.stack is non-standard and varies across browsers (and is a string), so we have to parse that stacktrace string + error message to turn it into structured data that sentry can understand.

I guess the other ask then here is, could we expose this as structured data instead of a logged out string? Could we throw additional fields into errorInfo aside from componentStack that we can just pick up in onRecoverableError?

@rickhanlonii
Copy link
Member

I do appreciate the need for structured error data, since I've implemented a few error dialogs like LogBox in React Native. But unfortunately the error message is not a public API and we may change it at any time between releases to optimize error creation and output.

Copy link

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

@github-actions github-actions bot added the Resolution: Stale Automatically closed due to inactivity label Aug 20, 2024
Copy link

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Stale Automatically closed due to inactivity
Projects
None yet
Development

No branches or pull requests

8 participants