Skip to content

Commit d73daeb

Browse files
authored
Merge pull request #13249 from getsentry/prepare-release/8.24.0
2 parents 62271a1 + 7c7e2e2 commit d73daeb

File tree

35 files changed

+410
-319
lines changed

35 files changed

+410
-319
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: "Install Playwright dependencies"
2+
description: "Installs Playwright dependencies and caches them."
3+
4+
runs:
5+
using: "composite"
6+
steps:
7+
- name: Get Playwright version
8+
id: playwright-version
9+
run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT
10+
shell: bash
11+
12+
- name: Cache playwright binaries
13+
uses: actions/cache@v4
14+
id: playwright-cache
15+
with:
16+
path: |
17+
~/.cache/ms-playwright
18+
key: playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }}
19+
20+
- name: Install Playwright dependencies (uncached)
21+
run: npx playwright install chromium webkit firefox --with-deps
22+
if: steps.playwright-cache.outputs.cache-hit != 'true'
23+
shell: bash
24+
25+
- name: Install Playwright system dependencies only (cached)
26+
run: npx playwright install-deps chromium webkit firefox
27+
if: steps.playwright-cache.outputs.cache-hit == 'true'
28+
shell: bash

.github/workflows/build.yml

Lines changed: 84 additions & 177 deletions
Large diffs are not rendered by default.

.github/workflows/flaky-test-detector.yml

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,8 @@ jobs:
4949
- name: Build packages
5050
run: yarn build
5151

52-
- name: Get npm cache directory
53-
id: npm-cache-dir
54-
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
55-
- name: Get Playwright version
56-
id: playwright-version
57-
run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT
58-
- uses: actions/cache@v4
59-
name: Check if Playwright browser is cached
60-
id: playwright-cache
61-
with:
62-
path: ${{ steps.npm-cache-dir.outputs.dir }}
63-
key: ${{ runner.os }}-Playwright-${{steps.playwright-version.outputs.version}}
64-
- name: Install Playwright browser if not cached
65-
if: steps.playwright-cache.outputs.cache-hit != 'true'
66-
run: npx playwright install --with-deps
67-
env:
68-
PLAYWRIGHT_BROWSERS_PATH: ${{steps.npm-cache-dir.outputs.dir}}
69-
- name: Install OS dependencies of Playwright if cache hit
70-
if: steps.playwright-cache.outputs.cache-hit == 'true'
71-
run: npx playwright install-deps
52+
- name: Install Playwright
53+
uses: ./.github/actions/install-playwright
7254

7355
- name: Determine changed tests
7456
uses: dorny/[email protected]

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010

1111
- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
1212

13+
## 8.24.0
14+
15+
- feat(nestjs): Filter RPC exceptions (#13227)
16+
- fix: Guard getReader function for other fetch implementations (#13246)
17+
- fix(feedback): Ensure feedback can be lazy loaded in CDN bundles (#13241)
18+
1319
## 8.23.0
1420

1521
### Important Changes
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
Sentry.init({
4+
dsn: 'https://[email protected]/1337',
5+
integrations: [],
6+
});
7+
8+
window.Sentry = {
9+
...Sentry,
10+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
window._testLazyLoadIntegration = async function run() {
2+
const integration = await window.Sentry.lazyLoadIntegration('feedbackIntegration');
3+
4+
window.Sentry.getClient()?.addIntegration(integration());
5+
6+
window._integrationLoaded = true;
7+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { expect } from '@playwright/test';
2+
import { SDK_VERSION } from '@sentry/browser';
3+
4+
import { sentryTest } from '../../../../utils/fixtures';
5+
6+
sentryTest('it allows to lazy load the feedback integration', async ({ getLocalTestUrl, page }) => {
7+
const bundle = process.env.PW_BUNDLE || '';
8+
const url = await getLocalTestUrl({ testDir: __dirname });
9+
10+
await page.route(`https://browser.sentry-cdn.com/${SDK_VERSION}/feedback.min.js`, route => {
11+
return route.fulfill({
12+
status: 200,
13+
contentType: 'application/javascript;',
14+
body: "window.Sentry.feedbackIntegration = () => ({ name: 'Feedback', attachTo: () => {} })",
15+
});
16+
});
17+
18+
await page.goto(url);
19+
20+
await page.waitForFunction('window.Sentry?.getClient()');
21+
22+
const integrationOutput1 = await page.evaluate('window.Sentry.feedbackIntegration?._isShim');
23+
24+
// Multiple cases are possible here:
25+
// 1. Bundle without feedback, should have _isShim property
26+
if (bundle.startsWith('bundle') && !bundle.includes('feedback')) {
27+
expect(integrationOutput1).toBe(true);
28+
} else {
29+
// 2. Either bundle with feedback, or ESM, should not have _isShim property
30+
expect(integrationOutput1).toBe(undefined);
31+
}
32+
33+
await page.evaluate('window._testLazyLoadIntegration()');
34+
await page.waitForFunction('window._integrationLoaded');
35+
36+
const integrationOutput2 = await page.evaluate('window.Sentry.feedbackIntegration?._isShim');
37+
expect(integrationOutput2).toBe(undefined);
38+
});

dev-packages/e2e-tests/Dockerfile.publish-packages

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ ARG NODE_VERSION=18.18.0
33
FROM node:${NODE_VERSION}
44

55
WORKDIR /sentry-javascript/dev-packages/e2e-tests
6-
CMD [ "yarn", "ts-node", "publish-packages.ts" ]
6+
CMD [ "yarn", "ts-node", "publish-packages.ts", "--transpile-only" ]

dev-packages/e2e-tests/publish-packages.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,22 @@ const packageTarballPaths = glob.sync('packages/*/sentry-*.tgz', {
1313
// Publish built packages to the fake registry
1414
packageTarballPaths.forEach(tarballPath => {
1515
// `--userconfig` flag needs to be before `publish`
16-
childProcess.execSync(`npm --userconfig ${__dirname}/test-registry.npmrc publish ${tarballPath}`, {
17-
cwd: repositoryRoot, // Can't use __dirname here because npm would try to publish `@sentry-internal/e2e-tests`
18-
encoding: 'utf8',
19-
stdio: 'inherit',
20-
});
16+
childProcess.exec(
17+
`npm --userconfig ${__dirname}/test-registry.npmrc publish ${tarballPath}`,
18+
{
19+
cwd: repositoryRoot, // Can't use __dirname here because npm would try to publish `@sentry-internal/e2e-tests`
20+
encoding: 'utf8',
21+
},
22+
(err, stdout, stderr) => {
23+
// eslint-disable-next-line no-console
24+
console.log(stdout);
25+
// eslint-disable-next-line no-console
26+
console.log(stderr);
27+
if (err) {
28+
// eslint-disable-next-line no-console
29+
console.error(err);
30+
process.exit(1);
31+
}
32+
},
33+
);
2134
});

dev-packages/e2e-tests/test-applications/aws-serverless-esm/start-event-proxy.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@ import { startEventProxyServer } from '@sentry-internal/test-utils';
33
startEventProxyServer({
44
port: 3031,
55
proxyServerName: 'aws-serverless-esm',
6-
forwardToSentry: false,
76
});

dev-packages/e2e-tests/test-applications/nestjs-basic/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"dependencies": {
1818
"@nestjs/common": "^10.0.0",
1919
"@nestjs/core": "^10.0.0",
20+
"@nestjs/microservices": "^10.0.0",
2021
"@nestjs/schedule": "^4.1.0",
2122
"@nestjs/platform-express": "^10.0.0",
2223
"@sentry/nestjs": "latest || *",

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Controller, Get, Param, ParseIntPipe, UseGuards, UseInterceptors } from '@nestjs/common';
2+
import { flush } from '@sentry/nestjs';
23
import { AppService } from './app.service';
34
import { ExampleGuard } from './example.guard';
45
import { ExampleInterceptor } from './example.interceptor';
@@ -49,6 +50,11 @@ export class AppController {
4950
return this.appService.testExpected500Exception(id);
5051
}
5152

53+
@Get('test-expected-rpc-exception/:id')
54+
async testExpectedRpcException(@Param('id') id: string) {
55+
return this.appService.testExpectedRpcException(id);
56+
}
57+
5258
@Get('test-span-decorator-async')
5359
async testSpanDecoratorAsync() {
5460
return { result: await this.appService.testSpanDecoratorAsync() };
@@ -63,4 +69,9 @@ export class AppController {
6369
async killTestCron() {
6470
this.appService.killTestCron();
6571
}
72+
73+
@Get('flush')
74+
async flush() {
75+
await flush();
76+
}
6677
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
2+
import { RpcException } from '@nestjs/microservices';
23
import { Cron, SchedulerRegistry } from '@nestjs/schedule';
34
import * as Sentry from '@sentry/nestjs';
45
import { SentryCron, SentryTraced } from '@sentry/nestjs';
@@ -38,6 +39,10 @@ export class AppService {
3839
throw new HttpException(`This is an expected 500 exception with id ${id}`, HttpStatus.INTERNAL_SERVER_ERROR);
3940
}
4041

42+
testExpectedRpcException(id: string) {
43+
throw new RpcException(`This is an expected RPC exception with id ${id}`);
44+
}
45+
4146
@SentryTraced('wait and return a string')
4247
async wait() {
4348
await new Promise(resolve => setTimeout(resolve, 500));

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,32 @@ test('Does not send HttpExceptions to Sentry', async ({ baseURL }) => {
6565
await transactionEventPromise400;
6666
await transactionEventPromise500;
6767

68-
await new Promise(resolve => setTimeout(resolve, 10000));
68+
(await fetch(`${baseURL}/flush`)).text();
69+
70+
expect(errorEventOccurred).toBe(false);
71+
});
72+
73+
test('Does not send RpcExceptions to Sentry', async ({ baseURL }) => {
74+
let errorEventOccurred = false;
75+
76+
waitForError('nestjs-basic', event => {
77+
if (!event.type && event.exception?.values?.[0]?.value === 'This is an expected RPC exception with id 123') {
78+
errorEventOccurred = true;
79+
}
80+
81+
return event?.transaction === 'GET /test-expected-rpc-exception/:id';
82+
});
83+
84+
const transactionEventPromise = waitForTransaction('nestjs-basic', transactionEvent => {
85+
return transactionEvent?.transaction === 'GET /test-expected-rpc-exception/:id';
86+
});
87+
88+
const response = await fetch(`${baseURL}/test-expected-rpc-exception/123`);
89+
expect(response.status).toBe(500);
90+
91+
await transactionEventPromise;
92+
93+
(await fetch(`${baseURL}/flush`)).text();
6994

7095
expect(errorEventOccurred).toBe(false);
7196
});

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Controller, Get, Param } from '@nestjs/common';
2+
import { flush } from '@sentry/nestjs';
23
import { AppService } from './app.service';
34

45
@Controller()
@@ -14,4 +15,9 @@ export class AppController {
1415
async testExpectedException(@Param('id') id: string) {
1516
return this.appService.testExpectedException(id);
1617
}
18+
19+
@Get('flush')
20+
async flush() {
21+
await flush();
22+
}
1723
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ test('Does not send exception to Sentry if user-defined global exception filter
8181

8282
await transactionEventPromise;
8383

84-
await new Promise(resolve => setTimeout(resolve, 10000));
84+
(await fetch(`${baseURL}/flush`)).text();
8585

8686
expect(errorEventOccurred).toBe(false);
8787
});
@@ -111,7 +111,7 @@ test('Does not send exception to Sentry if user-defined local exception filter a
111111

112112
await transactionEventPromise;
113113

114-
await new Promise(resolve => setTimeout(resolve, 10000));
114+
(await fetch(`${baseURL}/flush`)).text();
115115

116116
expect(errorEventOccurred).toBe(false);
117117
});

dev-packages/e2e-tests/test-applications/node-nestjs-basic/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"dependencies": {
1818
"@nestjs/common": "^10.0.0",
1919
"@nestjs/core": "^10.0.0",
20+
"@nestjs/microservices": "^10.0.0",
2021
"@nestjs/schedule": "^4.1.0",
2122
"@nestjs/platform-express": "^10.0.0",
2223
"@sentry/nestjs": "latest || *",

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Controller, Get, Param, ParseIntPipe, UseGuards, UseInterceptors } from '@nestjs/common';
2+
import { flush } from '@sentry/nestjs';
23
import { AppService } from './app.service';
34
import { ExampleGuard } from './example.guard';
45
import { ExampleInterceptor } from './example.interceptor';
@@ -49,6 +50,11 @@ export class AppController {
4950
return this.appService.testExpected500Exception(id);
5051
}
5152

53+
@Get('test-expected-rpc-exception/:id')
54+
async testExpectedRpcException(@Param('id') id: string) {
55+
return this.appService.testExpectedRpcException(id);
56+
}
57+
5258
@Get('test-span-decorator-async')
5359
async testSpanDecoratorAsync() {
5460
return { result: await this.appService.testSpanDecoratorAsync() };
@@ -63,4 +69,9 @@ export class AppController {
6369
async killTestCron() {
6470
this.appService.killTestCron();
6571
}
72+
73+
@Get('flush')
74+
async flush() {
75+
await flush();
76+
}
6677
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
2+
import { RpcException } from '@nestjs/microservices';
23
import { Cron, SchedulerRegistry } from '@nestjs/schedule';
34
import * as Sentry from '@sentry/nestjs';
45
import { SentryCron, SentryTraced } from '@sentry/nestjs';
@@ -38,6 +39,10 @@ export class AppService {
3839
throw new HttpException(`This is an expected 500 exception with id ${id}`, HttpStatus.INTERNAL_SERVER_ERROR);
3940
}
4041

42+
testExpectedRpcException(id: string) {
43+
throw new RpcException(`This is an expected RPC exception with id ${id}`);
44+
}
45+
4146
@SentryTraced('wait and return a string')
4247
async wait() {
4348
await new Promise(resolve => setTimeout(resolve, 500));

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,32 @@ test('Does not send HttpExceptions to Sentry', async ({ baseURL }) => {
6565
await transactionEventPromise400;
6666
await transactionEventPromise500;
6767

68-
await new Promise(resolve => setTimeout(resolve, 10000));
68+
(await fetch(`${baseURL}/flush`)).text();
69+
70+
expect(errorEventOccurred).toBe(false);
71+
});
72+
73+
test('Does not send RpcExceptions to Sentry', async ({ baseURL }) => {
74+
let errorEventOccurred = false;
75+
76+
waitForError('node-nestjs-basic', event => {
77+
if (!event.type && event.exception?.values?.[0]?.value === 'This is an expected RPC exception with id 123') {
78+
errorEventOccurred = true;
79+
}
80+
81+
return event?.transaction === 'GET /test-expected-rpc-exception/:id';
82+
});
83+
84+
const transactionEventPromise = waitForTransaction('node-nestjs-basic', transactionEvent => {
85+
return transactionEvent?.transaction === 'GET /test-expected-rpc-exception/:id';
86+
});
87+
88+
const response = await fetch(`${baseURL}/test-expected-rpc-exception/123`);
89+
expect(response.status).toBe(500);
90+
91+
await transactionEventPromise;
92+
93+
(await fetch(`${baseURL}/flush`)).text();
6994

7095
expect(errorEventOccurred).toBe(false);
7196
});

dev-packages/e2e-tests/test-applications/nuxt-3/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
},
1515
"dependencies": {
1616
"@sentry/nuxt": "latest || *",
17-
"nuxt": "3.11.2"
17+
"nuxt": "3.12.4"
1818
},
1919
"devDependencies": {
2020
"@nuxt/test-utils": "^3.13.1",

dev-packages/node-integration-tests/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
"@nestjs/core": "^10.3.3",
3232
"@nestjs/platform-express": "^10.3.3",
3333
"@prisma/client": "5.9.1",
34+
"@sentry/aws-serverless": "8.23.0",
3435
"@sentry/node": "8.23.0",
36+
"@sentry/utils": "8.23.0",
3537
"@sentry/types": "8.23.0",
3638
"@types/mongodb": "^3.6.20",
3739
"@types/mysql": "^2.15.21",

0 commit comments

Comments
 (0)