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

Allow users to supress hydration warning related errors at the Sentry level #6295

Closed
souredoutlook opened this issue Nov 24, 2022 · 51 comments · Fixed by getsentry/sentry#45188

Comments

@souredoutlook
Copy link
Member

Problem Statement

Using this code:

image

A Hydration warning will be raised. This is related to an existing issue in React 18. vercel/next.js#39425

This will result in a high volume of errors being logged by Sentry. which can only be mitigated by setting the supressHydrationWarning option

Solution Brainstorm

While the logged error is expected , the volume of these errors are unwelcome.

If possible, configure the ability to supress hydration warnings (and related errors) at the Sentry level. This would allow users to compromise by keeping the hydration warnings in app but skip reporting these via simple configuration.

@JamesSingleton
Copy link

Thank you for capturing this! 🙇🏼‍♂️

@lforst
Copy link
Member

lforst commented Nov 25, 2022

While I can see how these errors are annoying/flooding, usually they are valid and I advise against ignoring them and I am therefore on the fence about whether such an option is a good idea - best practice wise and also maintenance wise.

The code snipped is not telling enough about what exactly causes the mismatch between the SSR and the render on the client but I can only assume that somewhere in the render tree something like Date.now() or new Date() is called, which will most likely return different values on the client and on the server.

This is an antipattern that should be avoided. Instead of ignoring these errors, I recommend fixing them by storing them in a static state that is the same on the client and the server and that is then updated on mount (ie with useEffect). If you're on Next.js you can also use something like getServerSideProps to ensure a consistent value on the client and the server.

@dawsbot
Copy link

dawsbot commented Nov 28, 2022

So is @lforst saying that the OP's snippet is incomplete? The dynamic portion of this code which causes the warning is actually a dynamic Date somewhere higher in the render tree?

Because my application is massive and I have no idea where my hydration errors are coming from. Been burning through my Sentry quote for a few hundred dollars already with no bandwidth to spend days on this.

Would love to ignore all in Sentry like @souredoutlook proposed 🙏

@JamesSingleton
Copy link

So my application is deployed on Vercel and in the code snippet I take a date like 2022-11-22T16:58:45.679Z and pass it into const date = parseISO(dateString) and then format it.

@lforst
Copy link
Member

lforst commented Nov 28, 2022

@dawsbot I guess if your app is too large this ask makes sense. If you really want to ignore the errors via the SDK you can use the ignoreErrors or beforeSend options.

@dawsbot
Copy link

dawsbot commented Nov 29, 2022

@lforst would love a copy-pasteable snippet for beforeSend. I imagine there are a ton of other Nextjs users with this issue. Perhaps it's just me, but I've seen other devs with this warning in dev who continue to ignore it just like I do.

@dawsbot
Copy link

dawsbot commented Dec 3, 2022

Hey folks, my Sentry dashboard is unusable with the volume of these errors flowing in:
image

I followed the advice from @souredoutlook with no improvement:

image

@lforst
Copy link
Member

lforst commented Dec 5, 2022

ignoreErrors is case-sensitive so I definitely recommend you add Hydration to that array. What is weird though is that There was an error while hydrating this Suspense boundrary is still getting sent. Lemme look into this for a bit.

@lforst
Copy link
Member

lforst commented Dec 5, 2022

@dawsbot Ok just figured out why ignoreErrors isn't working. React throws minified errors and we're decoding them in the Sentry backend processing pipeline so that they're readable in the interface. The thing is the ignoreErrors option is applied client-side sent so we actually need to provide the minified errors in ignoreErrors. I guess this would look like the following:

ignoreErrors: [
  'https://reactjs.org/docs/error-decoder.html?invariant=423', // There was an error while hydrating.
  'https://reactjs.org/docs/error-decoder.html?invariant=425' // Text content does not match server-rendered HTML...
]

We might add an option for this in the future since this is a bit obscure but we will monitor the communitiy's need for this first to avoid API bloat.

@dawsbot
Copy link

dawsbot commented Dec 7, 2022

Uploaded! Will know if this helps soon @lforst 🙏

@geryit
Copy link

geryit commented Dec 11, 2022

did it work @dawsbot ?

@dawsbot
Copy link

dawsbot commented Dec 15, 2022

@geryit I cannot tell. My frontend error logging is swamped with these so since there's no hydration warning perhaps the original issue is fixed but it falls through to here?

image

@lforst
Copy link
Member

lforst commented Dec 15, 2022

@dawsbot I missed that one. Can you try the following if you find the time?:

ignoreErrors: [
  '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...
]

In general, if you want to ignore particular react errors, you can look them up here: https://github.com/facebook/react/blob/main/scripts/error-codes/codes.json

@dawsbot
Copy link

dawsbot commented Dec 20, 2022

@dawsbot I missed that one. Can you try the following if you find the time?:

ignoreErrors: [
  '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...
]

In general, if you want to ignore particular react errors, you can look them up here: https://github.com/facebook/react/blob/main/scripts/error-codes/codes.json

I think this worked! Thanks @lforst 🙏

@github-actions
Copy link
Contributor

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you label it Status: Backlog or Status: In Progress, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jan 19, 2023
@Merott
Copy link

Merott commented Jan 23, 2023

This has literally been driving me crazy for the past 2 months! 😬

Can we reopen this issue, please? At the very least, can we please have some documentation around the ignoreErrors config to explain how some errors might appear differently in Sentry than they would in the client-side filters?

It would've saved me days—no kidding! 😅

@lforst
Copy link
Member

lforst commented Jan 23, 2023

Can we reopen this issue, please? At the very least, can we please have some documentation around the ignoreErrors config to explain how some errors might appear differently in Sentry than they would in the client-side filters?

@Merott If you find a place in the docs where you would have found the information the most useful, feel free to open a PR and tag me and I'll review it!

@Merott
Copy link

Merott commented Jan 23, 2023

@lforst I think it would be useful to know how to check for the original error message, which can then be used in the filter.

When I looked in the JSON of the error events, the original error messages were nowhere to be found. It seems that they'd been entirely obscured by Sentry's backend processing pipeline.

If you'd point me to where/how to find the original message, I'd be happy to open a PR and save the next person's sanity! 😅

@HazAT
Copy link
Member

HazAT commented Jan 24, 2023

I am going to re-open this. We will figure out how to improve our product experience around this, stay tuned.

@HazAT HazAT reopened this Jan 24, 2023
@larsqa
Copy link

larsqa commented Feb 6, 2023

I've had similar issues for the past 4 days now, that I couldn't get ignoreErrors to work.

What annoys me most is that the SDK event payload is different from the event payload stored on Sentry's servers.

Too much "magic" is happening under the hood, making things confusing.

E.g. event.message (documented here), event.title or metadata.value never appears in the SDK event payload, but is the magically inferred in the data structure that Sentry saves in their backend.

That leads me to the question, on what field does ignoreErrors work?
I have to figure out via the beforeSend(event)=>{} hook, what is on the event payload and would first then be able to configure the ignoreErrors list properly.

@lforst
Copy link
Member

lforst commented Feb 6, 2023

@larsqa Our code for this isn't too complicated if you wanna read up on it:

return _getPossibleEventMessages(event).some(message => stringMatchesSomePattern(message, ignoreErrors));

In this particular case, we have to do the mapping/transformation serverside because we can't have a humungous list of react error code mappings stored in the SDK for bundle size reasons.

But as @HazAT already said we will try to find an in-product solution that will (at-least) make these errors way less noisy. Maybe we will also display a hint on how to ignore a particular react error server-side or smth like that.

@larsqa
Copy link

larsqa commented Feb 7, 2023

Thanks for linking to the source code of ignoreErrors.
As expected, it only works on the event.message field, which frequently is empty in the SDK event payload.

This makes the usage of ignoreErrors quite frustrating, as we can see the "message" in Sentry's Dashboard, but not in the SDK as we have no access to how you infer the message property.
A quick google search demonstrates this with plenty of GitHub issues, Stackoverflow questions or Sentry forum posts where people state that ignoreErrors does not work. Probably because the developers expect that they simply have to filter on the message value shown in Sentry dashboards.
Would it be possible to apply ignoreErrors to the SDK event payload properties that may be later on inferred for the message property too? I believe the event.exception.values[0].value may be one of them.

But as @HazAT already said we will try to find an in-product solution that will (at-least) make these errors way less noisy. Maybe we will also display a hint on how to ignore a particular react error server-side or smth like that.

While this sure helps, there are still plenty of edge cases that your "magic handling" won't cover, i.e. leading us back to above question to be more transparent, less "magic" one has to figure out themselves, and give the developer more control.

@jeengbe
Copy link
Contributor

jeengbe commented Feb 20, 2023

@lforst #6295 (comment)

@dawsbot Ok just figured out why ignoreErrors isn't working. React throws minified errors and we're decoding them in the Sentry backend processing pipeline so that they're readable in the interface. The thing is the ignoreErrors option is applied client-side sent so we actually need to provide the minified errors in ignoreErrors. I guess this would look like the following:

ignoreErrors: [
  'https://reactjs.org/docs/error-decoder.html?invariant=423', // There was an error while hydrating.
  'https://reactjs.org/docs/error-decoder.html?invariant=425' // Text content does not match server-rendered HTML...
]

We might add an option for this in the future since this is a bit obscure but we will monitor the communitiy's need for this first to avoid API bloat.

Something that hints of this is definitely needed. I have now spent a significant number of hours and deploys just for React errors to keep popping up the dashboard. While I'm just iterating and confirming what has been said already, particularly misleading was that the JSON blob Sentry gives doesn't match the one sent by the client. What complicated matters even more was that the property path was the exact same (exception > values > value), so its content overwritten by Sentry, which led me in the completely wrong direction.

image

And maybe a hovercard explaining what "originally" means here.

@larsqa
Copy link

larsqa commented Feb 20, 2023

@lforst @Lms24 @AbhiPrasad
Can this finally be assigned to a Sentry employee and taken further for an asap solution?

Multiple users, some with paid plans, have already raised their concerns (& frustration) that the current solution is just too ambiguous. In some of our integrations, we've wasted more than 20% of our Error Quota within 2 days just because of this issue - Error Quota we pay for!

@lforst
Copy link
Member

lforst commented Feb 20, 2023

Can this finally be assigned to a Sentry employee and taken further for an asap solution?

Multiple users, some with paid plans, have already raised their concerns (& frustration) that the current solution is just too ambiguous. In some of our integrations, we've wasted more than 20% of our Error Quota within 2 days just because of this issue - Error Quota we pay for!

@larsqa We are aware of this issue and that it is using quota. Fortunately, you already have the tool in your hands to ignore these errors. See #6295 (comment)

Something that hints of this is definitely needed. I have now spent a significant number of hours and deploys just for React errors to keep popping up the dashboard. While I'm just iterating and confirming what has been said already, particularly misleading was that the JSON blob Sentry gives doesn't match the one sent by the client. What complicated matters even more was that the property path was the exact same (exception > values > value), so its content overwritten by Sentry, which led me in the completely wrong direction.

@jeengbe

Our stance here is the following:

  • Having a link to the original JSON is probably not gonna happen. At least any time soon. It would come with too many considerations and storage concerns. It is very hard to discriminate between what has to be kept and what has to be removed. Consider an auth token in the payload we would normally strip. Should we keep it or strip it in the original payload JSON.
  • We notified the relevant team internally to work on the experience around explaining how to ignore particular react errors. This is likely gonna happen. Right now I cannot give a timeline for when exactly this is gonna happen.

@jeengbe
Copy link
Contributor

jeengbe commented Feb 20, 2023

@lforst I understand the concerns and am not arguing for keeping the data. I apologize if I was not clear in this. With that comment and the path, I tried to illustrate what added to the confusion, here it actually overwriting certain values found differently on the client.

@AbhiPrasad
Copy link
Member

We're going to be looking at making this easier to understand via the UI - task tracking this is here: getsentry/sentry#44877

In essence we're going to tell you exactly how/what to filter directly on the issue details page.

@larsqa
Copy link

larsqa commented Feb 21, 2023

@lforst We are aware of this issue and that it is using quota. Fortunately, you already have the tool in your hands to ignore these errors. See #6295 (comment)

While this solves the problem of this issue, it doesn't solve the general issue which is raised in here. ignoreErrors only works on one event property, the message. This is commonly empty on the SDK side and inferred on your side.
That you even went that far to translate https://reactjs.org/docs/error-decoder.html?invariant=422 to their actual meaning is just the cherry on top of the cake. If you apply these "extremely helpful developer features"(hint: satire), then at least be transparent enough about them so that we know that this happens.

The https://reactjs.org/docs/error-decoder.html?invariant=XXX types are the ones we know now about, thanks to this issue. However, what other messages do you decode that we are not aware of?

@jeengbe
Copy link
Contributor

jeengbe commented Feb 21, 2023

I agree with @larsqa and am happy to see you are addressing it!
While I don't support their sarcasm (I find transformations on your end very helpful), it is even more important to make users understand what is happening, and, as mentioned, don't make it an opaque process. I would've never thought about the possibility of Sentry altering event messages, which made it hard to find a solution to that issue.

In essence we're going to tell you exactly how/what to filter directly on the issue details page.

That sounds like a perfect solution, thank you.

@lforst
Copy link
Member

lforst commented Feb 21, 2023

The https://reactjs.org/docs/error-decoder.html?invariant=XXX types are the ones we know now about, thanks to this issue. However, what other messages do you decode that we are not aware of?

@larsqa As far as I am aware, none.

@HazAT
Copy link
Member

HazAT commented Feb 23, 2023

Hey, we had more internal conversations around this and decided to, for now, filter out hydration errors by default to not use up quota. Those errors are often not actionable (yet). We might find a way in the future to get more value out of them, but until then, we are filtering them out by default so that you can opt-out.
If you have opinions, please add them here to this issue:
getsentry/sentry#45038

@AbhiPrasad
Copy link
Member

I also created an issue in the react repo to see if we can make these errors better/more actionable: facebook/react#26224

Let's see what happens! Feel free to throw your thoughts in there as well.

@lforst
Copy link
Member

lforst commented Mar 3, 2023

Hi everyone! We just released an update on SaaS Sentry that filters out hydration errors by default without you having to change your SDK settings.

We decided to filter them because they are super unactionable and very noisy at the moment. Unfortunately react doesn't yet provide a way to determine the location of a hydration error in production mode. We opened an upstream issue for this over at facebook/react#26224. So if you want Sentry to tell you where your hydration errors happen, show that issue some love.

As I said, hydration errors should now be filtered by default. If you want to disable this behaviour to have hydration errors show up in your issue stream, you can flip the "Filter out hydration errors" switch on the "Inbound Filters" Project Settings:

image

@bscaspar
Copy link

bscaspar commented Apr 21, 2023

Thanks for implementing this feature! I see it's enabled by default which is great, and I'm seeing 227 errors filtered in the chart at the top of my page. However I am still seeing hydration errors reported:
Screenshot 2023-04-21 at 5 40 24 PM
and
Screenshot 2023-04-21 at 5 40 56 PM

Any idea why these might be getting through the filter?

Edit: adding the recommended minified React error URLs to the ignoreErrors array didn't help.

Edit 2: Turns out I needed to include a different minified react error from the above recommendations, "421": "This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition.",

@jiwon-mun
Copy link

Does it work at Replay?

It looks fine at Issue but not working replay.

@AbhiPrasad
Copy link
Member

@jiwon-mun this solution is an inbound filter, which means the error still might be tagged by the replay when being ingested. @bruno-garcia how does replay work with inbound filtered errors?

@OliverJAsh
Copy link
Contributor

"421": "This Suspense boundary received an update before it finished hydrating. This caused the boundary to switch to client rendering. The usual way to fix this is to wrap the original update in startTransition.",

Could we consider filtering these out as well? There are lots of false positives, for example: reduxjs/react-redux#1962.

@lforst
Copy link
Member

lforst commented Jun 10, 2024

@OliverJAsh My immediate instinct is not to filter these out by default. I also don't think the issue you linked is a false positive, at least the way I understood the problem.

I recommend you add https://react.dev/errors/421 to your ignoreErrors for now.

@OliverJAsh
Copy link
Contributor

Perhaps "false positive" was a poor choice of words. My understanding is that these errors can indicate performance issues but otherwise they're not errors that affect users. Furthermore, the error contains no information about the source of the issue, meaning the error isn't actionable.

As an aside, I spotted this PR which seems to remove these errors (?), although I'm not sure if it's been released yet.

I recommend you add https://react.dev/errors/421 to your ignoreErrors for now.

Thanks, we'll give that a go.

@lforst
Copy link
Member

lforst commented Jun 10, 2024

Furthermore, the error contains no information about the source of the issue, meaning the error isn't actionable.

That is actually a very valid reason to ignore the errors which I haven't considered yet. 🤔 Opened an issue: #12432

@RomanFausek
Copy link

I have tried to ignore hydration errors before sending them to Sentry but nothing worked. Any ideas? 🙏

#13539

@lforst
Copy link
Member

lforst commented Sep 2, 2024

@RomanFausek use the pattern I outlined here: #6295 (comment)

@RomanFausek
Copy link

@RomanFausek use the pattern I outlined here: #6295 (comment)

@lforst Only 421 is required? What about other errors? 422, 423, 425 etc?

@lforst
Copy link
Member

lforst commented Sep 2, 2024

@RomanFausek you can pick which ones to ignore. What I am trying to say is, please do

ignoreErrors: [
    'https://react.dev/errors/421',
],

instead of

ignoreErrors: [
    'https://reactjs.org/docs/error-decoder.html?invariant=421',
],

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

Successfully merging a pull request may close this issue.