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(nextjs): Add excludedServersideEntrypoints option #6125

Closed
wants to merge 7 commits into from

Conversation

lforst
Copy link
Member

@lforst lforst commented Nov 3, 2022

Resolves #6119

This PR adds a excludedServersideEntrypoints to our withSentryConfig Next.js config wrapper. It allows users to opt specific routes out of Sentry instrumentation, meaning the Sentry SDK won't be initialized for these routes.

The reason for this change is that we want to allow users to use different JavaScript runtimes for their Next.js routes. Up until now we just crashed the route.

The option takes an array containing strings or RegExes - strings match exactly, and RegExes match like they usually do.

@lforst lforst added this to the NextJS Improvements milestone Nov 3, 2022
@lforst lforst changed the title feat(nextjs): Add excludedServersideEntrypoints option allowing for opt-out of Sentry instrumentation feat(nextjs): Add excludedServersideEntrypoints option Nov 3, 2022
@lforst lforst marked this pull request as ready for review November 3, 2022 12:22
const relativePagePath = path
.join('pages', path.relative(pagesDir, this.resourcePath))
// Pull off the file extension
.replace(new RegExp(`\\.(${pageExtensionRegex})`), '');
Copy link
Member

Choose a reason for hiding this comment

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

m: do we need to worry about windows paths here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes and that should be taken care of by this implementation.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok actually went back and made sure that the path we match against is posix because it is just way easier for users to configure that way

packages/nextjs/src/config/types.ts Outdated Show resolved Hide resolved
packages/nextjs/src/config/types.ts Show resolved Hide resolved
lforst and others added 2 commits November 3, 2022 13:51
@smeubank smeubank mentioned this pull request Nov 3, 2022
2 tasks
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.

This approach looks good!

A few questions:

Are we meaning this to apply only to API routes, or to regular pages as well? I ask because as it stands, one couldn't exempt, say, pages/somePage. Your only option would be to block _app, which would turn the SDK off for all non-API pages besides _error. I think that if we are going to say it also applies to regular pages, we need to change our approach and (on the server side) insert the SDK into all page entrypoints (other than _app and _document) instead of just inserting it into _app.

If it really is for API routes only, should we reflect that reality in the option's name?

Also on the topic of naming (hardest problem in CS, right?): I have this dream that at some point we won't have to mess with entrypoints at all, and will do everything with our loaders. This makes me wonder if talking about entrypoints in the option name is too implementation-specific. Users think in terms of pages (or if this is really only for API routes, routes). Could we call it something like excludedServerSidePages or excludedAPIRoutes?

And one more thought - and then I'm done picking on the option name, I swear! - our naming convention for options tends to be verbNoun, not verbedNoun (see ignoreErrors, allowUrls, etc.) so regardless of any of the other questions, IMHO we should stick to that convention here as well.

(EDIT: Okay, I lied. One other thing I noticed is that in getServerSideProps, they capitalize the second S. Should we do that, too, just to be consistent?)

(Can you tell I used to have a side hustle as a copy editor? 😛)

@@ -34,11 +36,28 @@ export default async function proxyLoader(this: LoaderThis<LoaderOptions>, userC
// homepage), sub back in the root route
.replace(/^$/, '/');

// For the `excludedServersideEntrypoints` option we need the calculate the relative path to the file in question without file extension.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// For the `excludedServersideEntrypoints` option we need the calculate the relative path to the file in question without file extension.
// For the `excludedServersideEntrypoints` option we need to calculate the relative path to the file in question without file extension.

// For the `excludedServersideEntrypoints` option we need the calculate the relative path to the file in question without file extension.
const relativePosixPagePath = path
.join('pages', path.relative(pagesDir, this.resourcePath))
// Make sure that path is in posix style - this should make it easiser for users to configure and copy & paste from docs
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Make sure that path is in posix style - this should make it easiser for users to configure and copy & paste from docs
// Make sure that path is in posix style (using forward slashes) - this should make it easier for users to configure and will make docs examples work on all operating systems

Comment on lines +48 to +54
const isExcluded = excludedServersideEntrypoints.some(exludeEntry => {
if (typeof exludeEntry === 'string') {
return relativePosixPagePath === exludeEntry;
} else {
return relativePosixPagePath.match(exludeEntry);
}
});
Copy link
Member

Choose a reason for hiding this comment

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

L: I don't immediately have a great suggestion here, but the fact that we're comparing the excluded paths to the current path rather than vice versa makes my brain hurt a little. (When I put it into words in my head, it feels more intuitive to say "if the current path matches any of the excluded paths" rather than "if any of the excluded paths match the current path.")

Copy link
Member Author

Choose a reason for hiding this comment

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

I honestly wouldn't know how to stop the brain-hurting here :D We only have an array and a string to work with - can we even reverse this logic?

@@ -59,6 +59,15 @@ export type UserSentryOptions = {

// Automatically instrument Next.js data fetching methods and Next.js API routes
autoInstrumentServerFunctions?: boolean;

// Used to exclude certain serverside API routes or pages from being instrumented with Sentry. This option takes an
Copy link
Member

Choose a reason for hiding this comment

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

H: See above question re: if non-API pages should be part of this system.

packages/nextjs/src/config/types.ts Show resolved Hide resolved
function shouldAddSentryToEntryPoint(
entryPointName: string,
isServer: boolean,
excludedServersideEntrypoints: (string | RegExp)[],
Copy link
Member

Choose a reason for hiding this comment

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

L: If we set a default value here, we don't have to make sure to include the ?? [] every time we call this function.

Suggested change
excludedServersideEntrypoints: (string | RegExp)[],
excludedServersideEntrypoints: (string | RegExp)[] = [],

packages/nextjs/src/config/webpack.ts Outdated Show resolved Hide resolved
@lobsterkatie
Copy link
Member

Closing this in favor of a combination of #6206 and #6207.

lobsterkatie added a commit that referenced this pull request Nov 15, 2022
Currently, in the nextjs SDK, we inject the user's `Sentry.init()` code (by way of their `sentry.server.config.js` file) into all serverside routes. This adds a new option to the `sentry` object in `next.config.js` which allows users to prevent specific routes from being instrumented in this way. In this option, excluded routes can be specified using either strings (which need to exactly match the route) or regexes.

Note: Heavily inspired by #6125. h/t to @lforst for his work there. Compared to that PR, this one allows non-API routes to be excluded and allows excluded pages to be specified as routes rather than filepaths. (Using routes a) obviates the need for users to add `pages/` to the beginning of every entry, b) abstracts away the differences between windows and POSIX paths, and c) futureproofs users' config values against underlying changes to project file organization.)

Docs for this feature are being added in getsentry/sentry-docs#5789.

Fixes #6119.
Fixes #5964.
@AbhiPrasad AbhiPrasad deleted the lforst-route-opt-out branch November 20, 2022 16:11
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.

Provide Next.js SDK users with a way to opt out certain routes to use different runtimes
3 participants