ref(nextjs): Stop reinitializing the server SDK unnecessarily #3860
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.
In the nextjs SDK, we bundle the user's
Sentry.init()
code with every API route and with the_app
page, which is the basis of all user-provided pages. This is necessary because, when deployed on Vercel, each API route (and optionally each individual page) is turned into its own serverless function, so each one has to independently be able to start up the SDK.That said, a) not all nextjs apps are deployed to Vercel, and b) even those that are sometimes have multiple serverless API routes combined into a single serverless function. As a result,
Sentry.init()
can end up getting called over and over again, as different routes are hit on the same running server process. While we manage hubs and clients and scopes in such a way that this doesn't break anything, it's also a total waste of time - the startup code that we bundle with each route comes from a single source (sentry.server.config.js
) and therefore is the same for every route; once the SDK is started with the given options, it's started. No reason to do it multiple times.This PR thus introduces a check when calling the server-side
Sentry.init()
: if there is a client already defined on the current hub, it means the startup process has already run, and so it bails.The above change itself should be straightforward to review, but the test changes might be slightly more complicated to look at. TL;DR, because I needed the real
init()
from the node SDK to run (in order to create an already-initialized client to check), I switched the mocking of@sentry/node
from a direct mock to a pair of spies. I further did two renamings -s/mockInit/nodeInit
, to make it clear whichinit()
function we're talking about, ands/reactInitOptions/nodeInitOptions
, since this is the backend initialization we're testing rather than the front end.