fix(nextjs): Fix nock
wrapping conflict in integration tests
#4619
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.
Background
In our integration tests for nextjs, we use
nock
to intercept outgoing http requests, which lets us both examine a request’s payload (useful for seeing what would get sent to Sentry) and mock its response. As part of its initialization,nock
monkeypatches theget
andrequest
methods in both thehttp
andhttps
Node built-in modules. OurHttp
integration also monkeypatches those methods.There’s one key difference between our monkeypatching and their monkeypatching, however: while we always eventually call the method we’re wrapping,
nock
’s substitute methods only sometimes call the method being wrapped. In practical terms, what that means is that the order in which the two monkeypatching operations happen matters.If
nock
monkeypatches before we do, we effectively end up withsentryWrapper(nockWrapper(originalGet))
, which means that no matter whatnock
does or doesn’t do withoriginalGet
, our wrapper code will always run. But ifnock
monkeypatches after we do, we end up withnockWrapper(sentryWrapper(originalGet))
, meaning that ifnock
chooses not to call the function it’s wrapping, our code never runs.Up until now, the test we have for the
Http
integration has been working because it’s fallen into that first scenario. More specifically, the sequence of events when running the test has gone like this (monkeypatching steps have been starred):Starting with Nextjs 12.1, however, things go in a different order:
Note the new steps after (2), including the former (8) and (9), and the new version of (9). As we can see, the order of the monkeypatching has been reversed.
Cause
The reason for this change is this PR, which causes Next to load the
_app
and_document
pages as soon as the server starts, in the interest of serving the first requested page more quickly.Impact
The consequence of this change is that in our integration test of the
Http
integration, our wrapper code isn't called. As a result, the span the test expects will be created when it makes an http request isn't actually created, and the test fails.Solution
Though it's somewhat hacky, the solution in this PR is to force
get
(andrequest
, though that's irrelevant here) to be wrapped again by Sentry after they are wrapped bynock
. The result is a little messy, but fortunately turns out to be messy in ways which don't matter, as described in a comment in the new function which does the rewrapping:There are other comments (TODOs) in the code discussing a somewhat simpler strategy, but other work will need to be done first, and this should at least get CI unblocked.