Skip to content

Commit 28fa75f

Browse files
authored
Merge branch 'develop' into abhi-npm-run-all2
2 parents 1839364 + 0d558de commit 28fa75f

File tree

35 files changed

+922
-233
lines changed

35 files changed

+922
-233
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,7 @@ jobs:
10501050
'node-express-esm-preload',
10511051
'node-express-esm-without-loader',
10521052
'node-express-cjs-preload',
1053+
'node-otel-sdk-node',
10531054
'nextjs-app-dir',
10541055
'nextjs-14',
10551056
'nextjs-15',

dev-packages/browser-integration-tests/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"moduleResolution": "node",
77
"noEmit": true,
88
"strict": true,
9-
"allowSyntheticDefaultImports": true
9+
"allowSyntheticDefaultImports": true,
10+
"noUncheckedIndexedAccess": false
1011
},
1112
"include": ["**/*.ts"],
1213
"exclude": ["node_modules"]

dev-packages/browser-integration-tests/utils/generatePlugin.ts

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,9 @@ function generateSentryAlias(): Record<string, string> {
128128

129129
const modulePath = path.resolve(PACKAGES_DIR, packageName);
130130

131-
if (useCompiledModule && bundleKey && BUNDLE_PATHS[packageName]?.[bundleKey]) {
132-
const bundlePath = path.resolve(modulePath, BUNDLE_PATHS[packageName][bundleKey]);
131+
const bundleKeyPath = bundleKey && BUNDLE_PATHS[packageName]?.[bundleKey];
132+
if (useCompiledModule && bundleKeyPath) {
133+
const bundlePath = path.resolve(modulePath, bundleKeyPath);
133134

134135
return [packageJSON['name'], bundlePath];
135136
}
@@ -175,8 +176,8 @@ class SentryScenarioGenerationPlugin {
175176
(statement: { specifiers: [{ imported: { name: string } }] }, source: string) => {
176177
const imported = statement.specifiers?.[0]?.imported?.name;
177178

178-
if (imported && IMPORTED_INTEGRATION_CDN_BUNDLE_PATHS[imported]) {
179-
const bundleName = IMPORTED_INTEGRATION_CDN_BUNDLE_PATHS[imported];
179+
const bundleName = imported && IMPORTED_INTEGRATION_CDN_BUNDLE_PATHS[imported];
180+
if (bundleName) {
180181
this.requiredIntegrations.push(bundleName);
181182
} else if (source === '@sentry/wasm') {
182183
this.requiresWASMIntegration = true;
@@ -190,7 +191,7 @@ class SentryScenarioGenerationPlugin {
190191
HtmlWebpackPlugin.getHooks(compilation).alterAssetTags.tapAsync(this._name, (data, cb) => {
191192
if (useBundleOrLoader) {
192193
const bundleName = 'browser';
193-
const bundlePath = BUNDLE_PATHS[bundleName][bundleKey];
194+
const bundlePath = BUNDLE_PATHS[bundleName]?.[bundleKey];
194195

195196
if (!bundlePath) {
196197
throw new Error(`Could not find bundle or loader for key ${bundleKey}`);
@@ -215,10 +216,10 @@ class SentryScenarioGenerationPlugin {
215216
'__LOADER_OPTIONS__',
216217
JSON.stringify({
217218
dsn: 'https://[email protected]/1337',
218-
...loaderConfig.options,
219+
...loaderConfig?.options,
219220
}),
220221
)
221-
.replace('__LOADER_LAZY__', loaderConfig.lazy ? 'true' : 'false');
222+
.replace('__LOADER_LAZY__', loaderConfig?.lazy ? 'true' : 'false');
222223
});
223224
}
224225

@@ -240,36 +241,41 @@ class SentryScenarioGenerationPlugin {
240241
path.resolve(
241242
PACKAGES_DIR,
242243
'feedback',
243-
BUNDLE_PATHS['feedback'][integrationBundleKey].replace('[INTEGRATION_NAME]', integration),
244+
BUNDLE_PATHS['feedback']?.[integrationBundleKey]?.replace('[INTEGRATION_NAME]', integration) || '',
244245
),
245246
fileName,
246247
);
247248
});
248249
}
249250

250-
this.requiredIntegrations.forEach(integration => {
251-
const fileName = `${integration}.bundle.js`;
252-
addStaticAssetSymlink(
253-
this.localOutPath,
254-
path.resolve(
255-
PACKAGES_DIR,
256-
'browser',
257-
BUNDLE_PATHS['integrations'][integrationBundleKey].replace('[INTEGRATION_NAME]', integration),
258-
),
259-
fileName,
260-
);
251+
const baseIntegrationFileName = BUNDLE_PATHS['integrations']?.[integrationBundleKey];
261252

262-
const integrationObject = createHtmlTagObject('script', {
263-
src: fileName,
264-
});
253+
if (baseIntegrationFileName) {
254+
this.requiredIntegrations.forEach(integration => {
255+
const fileName = `${integration}.bundle.js`;
256+
addStaticAssetSymlink(
257+
this.localOutPath,
258+
path.resolve(
259+
PACKAGES_DIR,
260+
'browser',
261+
baseIntegrationFileName.replace('[INTEGRATION_NAME]', integration),
262+
),
263+
fileName,
264+
);
265265

266-
data.assetTags.scripts.unshift(integrationObject);
267-
});
266+
const integrationObject = createHtmlTagObject('script', {
267+
src: fileName,
268+
});
269+
270+
data.assetTags.scripts.unshift(integrationObject);
271+
});
272+
}
268273

269-
if (this.requiresWASMIntegration && BUNDLE_PATHS['wasm'][integrationBundleKey]) {
274+
const baseWasmFileName = BUNDLE_PATHS['wasm']?.[integrationBundleKey];
275+
if (this.requiresWASMIntegration && baseWasmFileName) {
270276
addStaticAssetSymlink(
271277
this.localOutPath,
272-
path.resolve(PACKAGES_DIR, 'wasm', BUNDLE_PATHS['wasm'][integrationBundleKey]),
278+
path.resolve(PACKAGES_DIR, 'wasm', baseWasmFileName),
273279
'wasm.bundle.js',
274280
);
275281

dev-packages/browser-integration-tests/utils/helpers.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,18 @@ const properFullEnvelopeParser = <T extends Envelope>(request: Request | null):
6565
};
6666

6767
function getEventAndTraceHeader(envelope: EventEnvelope): EventAndTraceHeader {
68-
const event = envelope[1][0][1] as Event;
69-
const trace = envelope[0].trace;
68+
const event = envelope[1][0]?.[1] as Event | undefined;
69+
const trace = envelope[0]?.trace;
70+
71+
if (!event || !trace) {
72+
throw new Error('Could not get event or trace from envelope');
73+
}
74+
7075
return [event, trace];
7176
}
7277

7378
export const properEnvelopeRequestParser = <T = Event>(request: Request | null, envelopeIndex = 1): T => {
74-
return properEnvelopeParser(request)[0][envelopeIndex] as T;
79+
return properEnvelopeParser(request)[0]?.[envelopeIndex] as T;
7580
};
7681

7782
export const properFullEnvelopeRequestParser = <T extends Envelope>(request: Request | null): T => {
@@ -361,7 +366,14 @@ async function getFirstSentryEnvelopeRequest<T>(
361366
url?: string,
362367
requestParser: (req: Request) => T = envelopeRequestParser as (req: Request) => T,
363368
): Promise<T> {
364-
return (await getMultipleSentryEnvelopeRequests<T>(page, 1, { url }, requestParser))[0];
369+
const reqs = await getMultipleSentryEnvelopeRequests<T>(page, 1, { url }, requestParser);
370+
371+
const req = reqs[0];
372+
if (!req) {
373+
throw new Error('No request found');
374+
}
375+
376+
return req;
365377
}
366378

367379
export { runScriptInSandbox, getMultipleSentryEnvelopeRequests, getFirstSentryEnvelopeRequest, getSentryEvents };

dev-packages/e2e-tests/test-applications/nestjs/src/app.controller.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ export class AppController1 {
4545
return this.appService.testException(id);
4646
}
4747

48+
@Get('test-expected-exception/:id')
49+
async testExpectedException(@Param('id') id: string) {
50+
return this.appService.testExpectedException(id);
51+
}
52+
4853
@Get('test-outgoing-fetch-external-allowed')
4954
async testOutgoingFetchExternalAllowed() {
5055
return this.appService.testOutgoingFetchExternalAllowed();

dev-packages/e2e-tests/test-applications/nestjs/src/app.service.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable } from '@nestjs/common';
1+
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
22
import * as Sentry from '@sentry/nestjs';
33
import { makeHttpRequest } from './utils';
44

@@ -52,6 +52,10 @@ export class AppService1 {
5252
throw new Error(`This is an exception with id ${id}`);
5353
}
5454

55+
testExpectedException(id: string) {
56+
throw new HttpException(`This is an expected exception with id ${id}`, HttpStatus.FORBIDDEN);
57+
}
58+
5559
async testOutgoingFetchExternalAllowed() {
5660
const fetchResponse = await fetch('http://localhost:3040/external-allowed');
5761

dev-packages/e2e-tests/test-applications/nestjs/tests/errors.test.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, test } from '@playwright/test';
2-
import { waitForError } from '@sentry-internal/test-utils';
2+
import { waitForError, waitForTransaction } from '@sentry-internal/test-utils';
33

44
test('Sends exception to Sentry', async ({ baseURL }) => {
55
const errorEventPromise = waitForError('nestjs', event => {
@@ -28,3 +28,28 @@ test('Sends exception to Sentry', async ({ baseURL }) => {
2828
span_id: expect.any(String),
2929
});
3030
});
31+
32+
test('Does not send expected exception to Sentry', async ({ baseURL }) => {
33+
let errorEventOccurred = false;
34+
35+
waitForError('nestjs', event => {
36+
if (!event.type && event.exception?.values?.[0]?.value === 'This is an expected exception with id 123') {
37+
errorEventOccurred = true;
38+
}
39+
40+
return event?.transaction === 'GET /test-expected-exception/:id';
41+
});
42+
43+
const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => {
44+
return transactionEvent?.transaction === 'GET /test-expected-exception/:id';
45+
});
46+
47+
const response = await fetch(`${baseURL}/test-expected-exception/123`);
48+
expect(response.status).toBe(403);
49+
50+
await transactionEventPromise;
51+
52+
await new Promise(resolve => setTimeout(resolve, 10000));
53+
54+
expect(errorEventOccurred).toBe(false);
55+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
dist
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
@sentry:registry=http://127.0.0.1:4873
2+
@sentry-internal:registry=http://127.0.0.1:4873
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "node-otel-sdk-trace",
3+
"version": "1.0.0",
4+
"private": true,
5+
"scripts": {
6+
"build": "tsc",
7+
"start": "node dist/app.js",
8+
"test": "playwright test",
9+
"clean": "npx rimraf node_modules pnpm-lock.yaml",
10+
"test:build": "pnpm install && pnpm build",
11+
"test:assert": "pnpm test"
12+
},
13+
"dependencies": {
14+
"@opentelemetry/sdk-node": "0.52.1",
15+
"@opentelemetry/exporter-trace-otlp-http": "0.52.1",
16+
"@sentry/core": "latest || *",
17+
"@sentry/node": "latest || *",
18+
"@sentry/opentelemetry": "latest || *",
19+
"@sentry/types": "latest || *",
20+
"@types/express": "4.17.17",
21+
"@types/node": "18.15.1",
22+
"express": "4.19.2",
23+
"typescript": "4.9.5"
24+
},
25+
"devDependencies": {
26+
"@playwright/test": "^1.44.1",
27+
"@sentry-internal/test-utils": "link:../../../test-utils"
28+
},
29+
"volta": {
30+
"extends": "../../package.json"
31+
}
32+
}

0 commit comments

Comments
 (0)