Skip to content

Commit 5b22b26

Browse files
authored
fix(nextjs): Fix matching logic for file convention type for root level components (#14038)
1 parent 7b815bf commit 5b22b26

File tree

3 files changed

+105
-74
lines changed

3 files changed

+105
-74
lines changed

.github/workflows/build.yml

+20-5
Original file line numberDiff line numberDiff line change
@@ -1035,14 +1035,19 @@ jobs:
10351035
overwrite: true
10361036
retention-days: 7
10371037

1038+
- name: Pre-process E2E Test Dumps
1039+
run: |
1040+
node ./scripts/normalize-e2e-test-dump-transaction-events.js
1041+
10381042
- name: Upload E2E Test Event Dumps
10391043
uses: actions/upload-artifact@v4
10401044
if: always()
10411045
with:
1042-
name: e2e-test-event-dumps
1046+
name: E2E Test Dump (${{ matrix.label || matrix.test-application }})
10431047
path: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}/event-dumps
10441048
overwrite: true
10451049
retention-days: 7
1050+
if-no-files-found: ignore
10461051

10471052
- name: Upload test results to Codecov
10481053
if: cancelled() == false
@@ -1083,10 +1088,6 @@ jobs:
10831088
'react-send-to-sentry',
10841089
'node-express-send-to-sentry',
10851090
'debug-id-sourcemaps',
1086-
'nextjs-app-dir',
1087-
'nextjs-13',
1088-
'nextjs-14',
1089-
'nextjs-15',
10901091
]
10911092
build-command:
10921093
- false
@@ -1184,6 +1185,20 @@ jobs:
11841185
timeout-minutes: 10
11851186
run: pnpm ${{ matrix.assert-command || 'test:assert' }}
11861187

1188+
- name: Pre-process E2E Test Dumps
1189+
run: |
1190+
node ./scripts/normalize-e2e-test-dump-transaction-events.js
1191+
1192+
- name: Upload E2E Test Event Dumps
1193+
uses: actions/upload-artifact@v4
1194+
if: always()
1195+
with:
1196+
name: E2E Test Dump (${{ matrix.label || matrix.test-application }})
1197+
path: dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}/event-dumps
1198+
overwrite: true
1199+
retention-days: 7
1200+
if-no-files-found: ignore
1201+
11871202
- name: Deploy Astro to Cloudflare
11881203
uses: cloudflare/pages-action@v1
11891204
if: matrix.test-application == 'cloudflare-astro'

packages/nextjs/src/config/loaders/wrappingLoader.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,10 @@ export default function wrappingLoader(
182182

183183
const componentTypeMatch = path.posix
184184
.normalize(path.relative(appDir, this.resourcePath))
185+
// Replace all backslashes with forward slashes (windows)
186+
.replace(/\\/g, '/')
185187
// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor
186-
.match(new RegExp(`/\\/?([^/]+)\\.(?:${pageExtensionRegex})$`));
188+
.match(new RegExp(`(?:^|/)?([^/]+)\\.(?:${pageExtensionRegex})$`));
187189

188190
if (componentTypeMatch && componentTypeMatch[1]) {
189191
let componentType: ServerComponentContext['componentType'];

scripts/normalize-e2e-test-dump-transaction-events.js

+82-68
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,95 @@
1+
// @ts-check
12
/* eslint-disable no-console */
23

34
const fs = require('fs');
45
const path = require('path');
6+
const glob = require('glob');
7+
8+
glob.glob(
9+
'../dev-packages/e2e-tests/test-applications/*/event-dumps/*.dump',
10+
{
11+
cwd: __dirname,
12+
absolute: true,
13+
},
14+
(err, dumpPaths) => {
15+
if (err) {
16+
throw err;
17+
}
518

6-
if (process.argv.length < 4) {
7-
throw new Error('Please provide an input and output file path as an argument.');
8-
}
9-
10-
const resolvedInputPath = path.resolve(process.argv[2]);
11-
const resolvedOutputPath = path.resolve(process.argv[3]);
12-
13-
const fileContents = fs.readFileSync(resolvedInputPath, 'utf8');
14-
15-
const transactionNodes = [];
16-
17-
fileContents.split('\n').forEach(serializedEnvelope => {
18-
let envelope;
19-
try {
20-
envelope = JSON.parse(serializedEnvelope);
21-
} catch (e) {
22-
return;
23-
// noop
24-
}
19+
dumpPaths.forEach(dumpPath => {
20+
const fileContents = fs.readFileSync(dumpPath, 'utf8');
2521

26-
const envelopeItems = envelope[1];
27-
28-
envelopeItems.forEach(([envelopeItemHeader, transaction]) => {
29-
if (envelopeItemHeader.type === 'transaction') {
30-
const rootNode = {
31-
runtime: transaction.contexts.runtime?.name,
32-
op: transaction.contexts.trace.op,
33-
name: transaction.transaction,
34-
children: [],
35-
};
36-
37-
const spanMap = new Map();
38-
spanMap.set(transaction.contexts.trace.span_id, rootNode);
39-
40-
transaction.spans.forEach(span => {
41-
const node = {
42-
op: span.data['sentry.op'],
43-
name: span.description,
44-
parent_span_id: span.parent_span_id,
45-
children: [],
46-
};
47-
spanMap.set(span.span_id, node);
48-
});
22+
const transactionNodes = [];
4923

50-
transaction.spans.forEach(span => {
51-
const node = spanMap.get(span.span_id);
52-
if (node && node.parent_span_id) {
53-
const parentNode = spanMap.get(node.parent_span_id);
54-
parentNode.children.push(node);
24+
fileContents.split('\n').forEach(serializedEnvelope => {
25+
let envelope;
26+
try {
27+
envelope = JSON.parse(serializedEnvelope);
28+
} catch (e) {
29+
return;
30+
// noop
5531
}
56-
});
5732

58-
transactionNodes.push(rootNode);
59-
}
60-
});
61-
});
62-
63-
const output = transactionNodes
64-
.sort((a, b) => {
65-
const aSerialized = serializeNode(a);
66-
const bSerialized = serializeNode(b);
67-
if (aSerialized < bSerialized) {
68-
return -1;
69-
} else if (aSerialized > bSerialized) {
70-
return 1;
71-
} else {
72-
return 0;
73-
}
74-
})
75-
.map(node => buildDeterministicStringFromNode(node))
76-
.join('\n\n-----------------------\n\n');
33+
const envelopeItems = envelope[1];
34+
35+
envelopeItems.forEach(([envelopeItemHeader, transaction]) => {
36+
if (envelopeItemHeader.type === 'transaction') {
37+
const rootNode = {
38+
runtime: transaction.contexts.runtime?.name,
39+
op: transaction.contexts.trace.op,
40+
name: transaction.transaction,
41+
children: [],
42+
};
43+
44+
const spanMap = new Map();
45+
spanMap.set(transaction.contexts.trace.span_id, rootNode);
46+
47+
transaction.spans.forEach(span => {
48+
const node = {
49+
op: span.data['sentry.op'],
50+
name: span.description,
51+
parent_span_id: span.parent_span_id,
52+
children: [],
53+
};
54+
spanMap.set(span.span_id, node);
55+
});
56+
57+
transaction.spans.forEach(span => {
58+
const node = spanMap.get(span.span_id);
59+
if (node && node.parent_span_id) {
60+
const parentNode = spanMap.get(node.parent_span_id);
61+
parentNode.children.push(node);
62+
}
63+
});
64+
65+
transactionNodes.push(rootNode);
66+
}
67+
});
68+
});
7769

78-
fs.writeFileSync(resolvedOutputPath, output, 'utf-8');
70+
const output = transactionNodes
71+
.sort((a, b) => {
72+
const aSerialized = serializeNode(a);
73+
const bSerialized = serializeNode(b);
74+
if (aSerialized < bSerialized) {
75+
return -1;
76+
} else if (aSerialized > bSerialized) {
77+
return 1;
78+
} else {
79+
return 0;
80+
}
81+
})
82+
.map(node => buildDeterministicStringFromNode(node))
83+
.join('\n\n-----------------------\n\n');
84+
85+
fs.writeFileSync(
86+
path.join(path.dirname(dumpPath), `normalized-transactions-${path.basename(dumpPath, '.dump')}.txt`),
87+
output,
88+
'utf-8',
89+
);
90+
});
91+
},
92+
);
7993

8094
// ------- utility fns ----------
8195

0 commit comments

Comments
 (0)