Skip to content

Commit 72c6855

Browse files
authored
fix(express): Support multiple routers with common paths. (#6253)
Handles the case when _at the end of reconstruction_ the original URL and the reconstructed URL don't match and there are no parameters.
1 parent daacd38 commit 72c6855

File tree

16 files changed

+329
-1
lines changed

16 files changed

+329
-1
lines changed

packages/node-integration-tests/.eslintrc.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ module.exports = {
1818
project: ['tsconfig.test.json'],
1919
sourceType: 'module',
2020
},
21+
rules: {
22+
'@typescript-eslint/typedef': 'off',
23+
},
2124
},
2225
],
2326
};
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as Sentry from '@sentry/node';
2+
import * as Tracing from '@sentry/tracing';
3+
import cors from 'cors';
4+
import express from 'express';
5+
6+
const app = express();
7+
8+
Sentry.init({
9+
dsn: 'https://[email protected]/1337',
10+
release: '1.0',
11+
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
12+
tracesSampleRate: 1.0,
13+
});
14+
15+
app.use(Sentry.Handlers.requestHandler());
16+
app.use(Sentry.Handlers.tracingHandler());
17+
18+
app.use(cors());
19+
20+
const APIv1 = express.Router();
21+
22+
APIv1.get('/user/:userId', function (_req, res) {
23+
Sentry.captureMessage('Custom Message');
24+
res.send('Success');
25+
});
26+
27+
const root = express.Router();
28+
29+
app.use('/api2/v1', root);
30+
app.use('/api/v1', APIv1);
31+
32+
app.use(Sentry.Handlers.errorHandler());
33+
34+
export default app;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { assertSentryEvent, TestEnv } from '../../../../utils/index';
2+
3+
test('should construct correct url with common infixes with multiple parameterized routers.', async () => {
4+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
5+
const event = await env.getEnvelopeRequest({ url: env.url.replace('test', 'api/v1/user/3212') });
6+
7+
assertSentryEvent(event[2] as any, {
8+
message: 'Custom Message',
9+
transaction: 'GET /api/v1/user/:userId',
10+
});
11+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as Sentry from '@sentry/node';
2+
import * as Tracing from '@sentry/tracing';
3+
import cors from 'cors';
4+
import express from 'express';
5+
6+
const app = express();
7+
8+
Sentry.init({
9+
dsn: 'https://[email protected]/1337',
10+
release: '1.0',
11+
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
12+
tracesSampleRate: 1.0,
13+
});
14+
15+
app.use(Sentry.Handlers.requestHandler());
16+
app.use(Sentry.Handlers.tracingHandler());
17+
18+
app.use(cors());
19+
20+
const APIv1 = express.Router();
21+
22+
APIv1.get('/test', function (_req, res) {
23+
Sentry.captureMessage('Custom Message');
24+
res.send('Success');
25+
});
26+
27+
const root = express.Router();
28+
29+
app.use('/api/v1', root);
30+
app.use('/api2/v1', APIv1);
31+
32+
app.use(Sentry.Handlers.errorHandler());
33+
34+
export default app;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { assertSentryEvent, TestEnv } from '../../../../utils/index';
2+
3+
test('should construct correct url with common infixes with multiple routers.', async () => {
4+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
5+
const event = await env.getEnvelopeRequest({ url: env.url.replace('test', 'api2/v1/test/') });
6+
7+
assertSentryEvent(event[2] as any, {
8+
message: 'Custom Message',
9+
transaction: 'GET /api2/v1/test',
10+
});
11+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as Sentry from '@sentry/node';
2+
import * as Tracing from '@sentry/tracing';
3+
import cors from 'cors';
4+
import express from 'express';
5+
6+
const app = express();
7+
8+
Sentry.init({
9+
dsn: 'https://[email protected]/1337',
10+
release: '1.0',
11+
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
12+
tracesSampleRate: 1.0,
13+
});
14+
15+
app.use(Sentry.Handlers.requestHandler());
16+
app.use(Sentry.Handlers.tracingHandler());
17+
18+
app.use(cors());
19+
20+
const APIv1 = express.Router();
21+
22+
APIv1.get('/user/:userId', function (_req, res) {
23+
Sentry.captureMessage('Custom Message');
24+
res.send('Success');
25+
});
26+
27+
const root = express.Router();
28+
29+
app.use('/api/v1', APIv1);
30+
app.use('/api', root);
31+
32+
app.use(Sentry.Handlers.errorHandler());
33+
34+
export default app;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { assertSentryEvent, TestEnv } from '../../../../utils/index';
2+
3+
test('should construct correct urls with multiple parameterized routers (use order reversed).', async () => {
4+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
5+
const event = await env.getEnvelopeRequest({ url: env.url.replace('test', 'api/v1/user/1234/') });
6+
7+
assertSentryEvent(event[2] as any, {
8+
message: 'Custom Message',
9+
transaction: 'GET /api/v1/user/:userId',
10+
});
11+
});
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as Sentry from '@sentry/node';
2+
import * as Tracing from '@sentry/tracing';
3+
import cors from 'cors';
4+
import express from 'express';
5+
6+
const app = express();
7+
8+
Sentry.init({
9+
dsn: 'https://[email protected]/1337',
10+
release: '1.0',
11+
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
12+
tracesSampleRate: 1.0,
13+
});
14+
15+
app.use(Sentry.Handlers.requestHandler());
16+
app.use(Sentry.Handlers.tracingHandler());
17+
18+
app.use(cors());
19+
20+
const APIv1 = express.Router();
21+
22+
APIv1.get('/user/:userId', function (_req, res) {
23+
Sentry.captureMessage('Custom Message');
24+
res.send('Success');
25+
});
26+
27+
const root = express.Router();
28+
29+
app.use('/api', root);
30+
app.use('/api/v1', APIv1);
31+
32+
app.use(Sentry.Handlers.errorHandler());
33+
34+
export default app;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { assertSentryEvent, TestEnv } from '../../../../utils/index';
2+
3+
test('should construct correct urls with multiple parameterized routers.', async () => {
4+
const env = await TestEnv.init(__dirname, `${__dirname}/server.ts`);
5+
const event = await env.getEnvelopeRequest({ url: env.url.replace('test', 'api/v1/user/1234/') });
6+
7+
assertSentryEvent(event[2] as any, {
8+
message: 'Custom Message',
9+
transaction: 'GET /api/v1/user/:userId',
10+
});
11+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as Sentry from '@sentry/node';
2+
import * as Tracing from '@sentry/tracing';
3+
import cors from 'cors';
4+
import express from 'express';
5+
6+
const app = express();
7+
8+
Sentry.init({
9+
dsn: 'https://[email protected]/1337',
10+
release: '1.0',
11+
integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })],
12+
tracesSampleRate: 1.0,
13+
});
14+
15+
app.use(Sentry.Handlers.requestHandler());
16+
app.use(Sentry.Handlers.tracingHandler());
17+
18+
app.use(cors());
19+
20+
const APIv1 = express.Router();
21+
22+
APIv1.get('/:userId', function (_req, res) {
23+
Sentry.captureMessage('Custom Message');
24+
res.send('Success');
25+
});
26+
27+
const root = express.Router();
28+
29+
app.use('/api/v1', APIv1);
30+
app.use('/api', root);
31+
32+
app.use(Sentry.Handlers.errorHandler());
33+
34+
export default app;

0 commit comments

Comments
 (0)