Skip to content

Commit a6c44af

Browse files
fix(tracing-internal): Remove query params from urls with a trailing slash (#9328)
fix use case when original req url ends with trailing slash and contains query params. Example: `api/v1/users/123/posts/?param=1`
1 parent 9218eaa commit a6c44af

File tree

2 files changed

+53
-1
lines changed
  • packages
    • node-integration-tests/suites/express/multiple-routers/complex-router
    • tracing-internal/src/node/integrations

2 files changed

+53
-1
lines changed

packages/node-integration-tests/suites/express/multiple-routers/complex-router/test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,55 @@ test('should construct correct url with multiple parameterized routers, when par
2525
});
2626
}
2727
});
28+
29+
test('should construct correct url with multiple parameterized routers, when param is also contain in middle layer route and express used multiple middlewares with route and original url has query params', async () => {
30+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
31+
const event = await env.getEnvelopeRequest({
32+
url: env.url.replace('test', 'api/api/v1/sub-router/users/123/posts/456?param=1'),
33+
envelopeType: 'transaction',
34+
});
35+
// parse node.js major version
36+
const [major] = process.versions.node.split('.').map(Number);
37+
// Split test result base on major node version because regex d flag is support from node 16+
38+
if (major >= 16) {
39+
assertSentryEvent(event[2] as any, {
40+
transaction: 'GET /api/api/v1/sub-router/users/:userId/posts/:postId',
41+
transaction_info: {
42+
source: 'route',
43+
},
44+
});
45+
} else {
46+
assertSentryEvent(event[2] as any, {
47+
transaction: 'GET /api/api/v1/sub-router/users/123/posts/:postId',
48+
transaction_info: {
49+
source: 'route',
50+
},
51+
});
52+
}
53+
});
54+
55+
test('should construct correct url with multiple parameterized routers, when param is also contain in middle layer route and express used multiple middlewares with route and original url ends with trailing slash and has query params', async () => {
56+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
57+
const event = await env.getEnvelopeRequest({
58+
url: env.url.replace('test', 'api/api/v1/sub-router/users/123/posts/456/?param=1'),
59+
envelopeType: 'transaction',
60+
});
61+
// parse node.js major version
62+
const [major] = process.versions.node.split('.').map(Number);
63+
// Split test result base on major node version because regex d flag is support from node 16+
64+
if (major >= 16) {
65+
assertSentryEvent(event[2] as any, {
66+
transaction: 'GET /api/api/v1/sub-router/users/:userId/posts/:postId',
67+
transaction_info: {
68+
source: 'route',
69+
},
70+
});
71+
} else {
72+
assertSentryEvent(event[2] as any, {
73+
transaction: 'GET /api/api/v1/sub-router/users/123/posts/:postId',
74+
transaction_info: {
75+
source: 'route',
76+
},
77+
});
78+
}
79+
});

packages/tracing-internal/src/node/integrations/express.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ function instrumentRouter(appOrRouter: ExpressRouter): void {
358358
// Now we check if we are in the "last" part of the route. We determine this by comparing the
359359
// number of URL segments from the original URL to that of our reconstructed parameterized URL.
360360
// If we've reached our final destination, we update the transaction name.
361-
const urlLength = getNumberOfUrlSegments(req.originalUrl || '') + numExtraSegments;
361+
const urlLength = getNumberOfUrlSegments(stripUrlQueryAndFragment(req.originalUrl || '')) + numExtraSegments;
362362
const routeLength = getNumberOfUrlSegments(req._reconstructedRoute);
363363

364364
if (urlLength === routeLength) {

0 commit comments

Comments
 (0)