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

feat: Add ensureNoCircularStructures experiment to help debug serialization bugs #3776

Merged
merged 4 commits into from Jul 7, 2021

Conversation

kamilogorek
Copy link
Contributor

ref: #2809

We don't want to expose this publicly, as it may be costly to normalize every event in its entirety (keep in mind that it defaults to infinite depth, but will break recursive cycles) but should be useful to expose what is triggering serialization issues in some cases.

@kamilogorek kamilogorek requested a review from HazAT July 1, 2021 10:05
@github-actions
Copy link
Contributor

github-actions bot commented Jul 1, 2021

size-limit report

Path Size
@sentry/browser - CDN Bundle (gzipped) 21.43 KB (+0.19% 🔺)
@sentry/browser - Webpack 22.45 KB (+0.22% 🔺)
@sentry/react - Webpack 22.49 KB (+0.22% 🔺)
@sentry/browser + @sentry/tracing - CDN Bundle (gzipped) 28.92 KB (+0.12% 🔺)

@kamilogorek kamilogorek requested review from a team, lobsterkatie and rhcarvalho and removed request for a team July 1, 2021 10:23
Copy link
Contributor

@rhcarvalho rhcarvalho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add test(s)?

What could possibly go wrong calling normalize(normalized)?

Copy link
Member

@lobsterkatie lobsterkatie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kamilogorek
Copy link
Contributor Author

@rhcarvalho we already have 300LoC tests around it 😅
https://github.com/getsentry/sentry-javascript/blob/master/packages/utils/test/object.test.ts#L107-L544

Nothing should(tm) go wrong, as this util is tested throughout, but it can just be costly with larger and more intensive payloads numbers. This will not be documented nor publicly exposed in any way, but we can ask customers/GH people to use it and get more insights at very little cost (bundle size wise) as it's optimized to a single LoC.

@kamilogorek kamilogorek merged commit 8bd8243 into master Jul 7, 2021
@kamilogorek kamilogorek deleted the nocircular-experiment branch July 7, 2021 09:33
lobsterkatie added a commit that referenced this pull request Jan 24, 2022
Since at least 5.19.1, we've had a bug[1] which causes events not to be able to be serialized for transmission, because they contain circular references. In theory, this should never happen, because all events go through a normalization process which [removes circular references](https://github.com/getsentry/sentry-javascript/blob/6abb46374763a49b60b883e1190d5dfda8eda842/packages/utils/src/object.ts#L338-L341). Nonetheless, the problem persists.

There are three possibilities:

1) The normalization function is somehow not getting called for certain events.

2) Data containing a circular reference is being added to the event between normalization and serialization.

3) The normalization function doesn't catch (and fix) all cases in which circular references exist.

In #3776, a debug flag was added which causes normalization to run twice, as a way to protect against possibility 1. As described in the above-linked issue, though, this hasn't solved the problem, at least not completely, as the serialization error is still occurring for some people.

This PR aims to improve on that initial debugging step, by making the following changes:

- The initial attempt at serialization is wrapped in a try-catch, so that any errors that arise can be collected _alongside_ the real event (as a `JSONStringifyError` tag and as a stacktrace in `event.extra`), rather than instead of it.

- Events which go through the initial normalization are tagged internally, so that if the serializer encounters an event which _doesn't_ have the tag, it can note that (as a `skippedNormalization` tag on the event). In theory this should never show up, but if it does, it points to possibility 1.

- Renormalization has been moved so that it's part of the serialization process itself. If this fixes the problem, that points to possibility 2.

- Renormalization has been wrapped in a try-catch, with a `JSON.stringify error after renormalization` event logged to Sentry (again with the error in `extra` data) in cases where it fails. This is another situation which should never happen, but if it does, it points to possibility 3.

Also, this is not specifically for debugging, but a bonus side effect of moving the renormalization to be part of serialization is that it allows us to only renormalize if theres's a problem, which eliminates a relatively computationally expensive operation in cases where it's not needed and therefore lets us ditch the debug flag. 

P.S. Disclaimer: I know this isn't all that pretty, but my assumption is that this will stay in the SDK for a release or two while we (hopefully) finally solve the mystery, and then be pulled back out before we ship v7.

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

Successfully merging this pull request may close these issues.

None yet

3 participants