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

fix(react): Fix React Router v6 paramaterization #5515

Merged
merged 4 commits into from Aug 3, 2022

Conversation

AbhiPrasad
Copy link
Member

@AbhiPrasad AbhiPrasad commented Aug 2, 2022

Fixes #5513

Make sure paramaterization occurs in scenarios where the full path is not available after all the branches are walked. In those scenarios, we have to construct the paramaterized name based on the previous branches that were analyzed.

This patch also creates a new file in @sentry/utils - url.ts, where we store some url / string related utils. This was made so that the react package would get access to the getNumberOfUrlSegments util.

Make sure paramaterization occurs in scenarios where the full path is
not avaliable after all the branches are walked. In those scenarios, we
have to construct the paramaterized name based on the previous branches
that were analyzed.
@AbhiPrasad AbhiPrasad requested review from onurtemizkan, a team, lforst and Lms24 and removed request for a team August 2, 2022 19:46
@AbhiPrasad AbhiPrasad self-assigned this Aug 2, 2022
Copy link
Member

@Lms24 Lms24 left a comment

Choose a reason for hiding this comment

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

LGTM! One optional suggestion.

Btw: Does RR6 offer regex or route array support, similar to Express? Probably not but I thought I'd ask since I came across some edge cases there.

Comment on lines 113 to 114
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let x = 0; x < branches.length; x++) {
Copy link
Member

Choose a reason for hiding this comment

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

Just out of curiosity: why the index for loop?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's to stay consistent with RR5 integration. Not sure if there's any specific reason there though.

// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let x = 0; x < branches.length; x++) {
if (branches[x].match.isExact) {
return [branches[x].match.path, 'route'];
}
}

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'll just keep the explicit for loop, though technically it is extra bytes

// If the route defined on the element is something like
// <Route path="/stores/:storeId/products/:productId" element={<div>Product</div>} />
// We should check against the branch.pathname for the number of / seperators
if (pathBuilder.split('/').length !== branch.pathname.split('/').length) {
Copy link
Member

@Lms24 Lms24 Aug 3, 2022

Choose a reason for hiding this comment

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

Is this a safe check? Just asking because I used URL segment counting in my Express router instrumentation and I had to handle a few edge cases. For example, could there be problems with routes starting or ending with a / while others don't? (which would influence the length because of empty array items after the .split operation).

Just a suggestion but now that I'm thinking about it, we could extract this function

/**
* Returns number of URL segments of a passed URL.
* Also handles URLs of type RegExp
*/
function getNumberOfUrlSegments(url: string): number {
// split at '/' or at '\/' to split regex urls correctly
return url.split(/\\?\//).filter(s => s.length > 0 && s !== ',').length;
}

to our utils package and use it here. But totally optional ofc.

Copy link
Member Author

Choose a reason for hiding this comment

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

Great point! I'm going to extract out getNumberOfUrlSegments and use it instead.

@AbhiPrasad
Copy link
Member Author

AbhiPrasad commented Aug 3, 2022

Btw: Does RR6 offer regex or route array support, similar to Express? Probably not but I thought I'd ask since I came across some edge cases there.

Previous versions did offer regex/array support - this one no longer does, so I think we are fine here.

Edit: https://reactrouter.com/docs/en/v6/getting-started/faq#what-happened-to-regexp-routes-paths

return {};
}

const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data

This [regular expression](1) that depends on [library input](2) may run slow on strings with many repetitions of '"'.
@AbhiPrasad AbhiPrasad enabled auto-merge (squash) August 3, 2022 19:38
@github-actions
Copy link
Contributor

github-actions bot commented Aug 3, 2022

size-limit report 📦

Path Size
@sentry/browser - ES5 CDN Bundle (gzipped + minified) 19.36 KB (0%)
@sentry/browser - ES5 CDN Bundle (minified) 59.95 KB (0%)
@sentry/browser - ES6 CDN Bundle (gzipped + minified) 17.94 KB (+0.02% 🔺)
@sentry/browser - ES6 CDN Bundle (minified) 52.83 KB (0%)
@sentry/browser - Webpack (gzipped + minified) 19.7 KB (-0.01% 🔽)
@sentry/browser - Webpack (minified) 64.16 KB (-0.01% 🔽)
@sentry/react - Webpack (gzipped + minified) 19.72 KB (+0.01% 🔺)
@sentry/nextjs Client - Webpack (gzipped + minified) 44.14 KB (+0.05% 🔺)
@sentry/browser + @sentry/tracing - ES5 CDN Bundle (gzipped + minified) 25.76 KB (-0.02% 🔽)
@sentry/browser + @sentry/tracing - ES6 CDN Bundle (gzipped + minified) 24.02 KB (+0.01% 🔺)

@AbhiPrasad AbhiPrasad merged commit f0ab0e0 into master Aug 3, 2022
@AbhiPrasad AbhiPrasad deleted the abhi-react-router-v6-fix branch August 3, 2022 20:02
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.

Transaction names are not properly parameterized with react-router v6
3 participants