Skip to content

Commit 75e5c14

Browse files
authored
Merge branch 'develop' into abhi-express-normalized-request
2 parents 128475f + e61377c commit 75e5c14

28 files changed

+445
-110
lines changed

dev-packages/e2e-tests/test-applications/sveltekit-2.5.0-twp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"@sentry-internal/test-utils": "link:../../../test-utils",
2323
"@sentry/core": "latest || *",
2424
"@sveltejs/adapter-auto": "^3.0.0",
25-
"@sveltejs/kit": "2.5.0",
25+
"@sveltejs/kit": "2.8.3",
2626
"@sveltejs/vite-plugin-svelte": "^3.0.0",
2727
"svelte": "^5.0.0-next.115",
2828
"svelte-check": "^3.6.0",

packages/browser/test/tracekit/chromium.test.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,4 +643,97 @@ describe('Tracekit - Chrome Tests', () => {
643643
},
644644
});
645645
});
646+
647+
it('should correctly parse a wasm stack trace', () => {
648+
const WASM_ERROR = {
649+
message: 'memory access out of bounds',
650+
name: 'RuntimeError',
651+
stack: `RuntimeError: memory access out of bounds
652+
at MyClass::bar(int) const (http://localhost:8001/main.wasm:wasm-function[190]:0x5aeb)
653+
at MyClass::foo(int) const (http://localhost:8001/main.wasm:wasm-function[186]:0x5637)
654+
at MyClass::getAt(int) const (http://localhost:8001/main.wasm:wasm-function[182]:0x540b)
655+
at emscripten::internal::MethodInvoker<int (MyClass::*)(int) const, int, MyClass const*, int>::invoke(int (MyClass::* const&)(int) const, MyClass const*, int) (http://localhost:8001/main.wasm:wasm-function[152]:0x47df)
656+
at ClassHandle.MyClass$getAt [as getAt] (eval at newFunc (http://localhost:8001/main.js:2201:27), <anonymous>:9:10)
657+
at myFunctionVectorOutOfBounds (http://localhost:8001/main.html:18:22)
658+
at captureError (http://localhost:8001/main.html:27:11)
659+
at Object.onRuntimeInitialized (http://localhost:8001/main.html:39:9)
660+
at doRun (http://localhost:8001/main.js:7084:71)
661+
at run (http://localhost:8001/main.js:7101:5)`,
662+
};
663+
664+
const ex = exceptionFromError(parser, WASM_ERROR);
665+
666+
// This is really ugly but the wasm integration should clean up these stack frames
667+
expect(ex).toStrictEqual({
668+
stacktrace: {
669+
frames: [
670+
{
671+
colno: 5,
672+
filename: 'http://localhost:8001/main.js',
673+
function: 'run',
674+
in_app: true,
675+
lineno: 7101,
676+
},
677+
{
678+
colno: 71,
679+
filename: 'http://localhost:8001/main.js',
680+
function: 'doRun',
681+
in_app: true,
682+
lineno: 7084,
683+
},
684+
{
685+
colno: 9,
686+
filename: 'http://localhost:8001/main.html',
687+
function: 'Object.onRuntimeInitialized',
688+
in_app: true,
689+
lineno: 39,
690+
},
691+
{
692+
colno: 11,
693+
filename: 'http://localhost:8001/main.html',
694+
function: 'captureError',
695+
in_app: true,
696+
lineno: 27,
697+
},
698+
{
699+
colno: 22,
700+
filename: 'http://localhost:8001/main.html',
701+
function: 'myFunctionVectorOutOfBounds',
702+
in_app: true,
703+
lineno: 18,
704+
},
705+
{
706+
colno: 27,
707+
filename: 'http://localhost:8001/main.js',
708+
function: 'ClassHandle.MyClass$getAt [as getAt]',
709+
in_app: true,
710+
lineno: 2201,
711+
},
712+
{
713+
filename:
714+
'int) const, int, MyClass const*, int>::invoke(int (MyClass::* const&)(int) const, MyClass const*, int) (http://localhost:8001/main.wasm:wasm-function[152]:0x47df',
715+
function: 'emscripten::internal::MethodInvoker<int (MyClass::*)',
716+
in_app: true,
717+
},
718+
{
719+
filename: 'int) const (http://localhost:8001/main.wasm:wasm-function[182]:0x540b',
720+
function: 'MyClass::getAt',
721+
in_app: true,
722+
},
723+
{
724+
filename: 'int) const (http://localhost:8001/main.wasm:wasm-function[186]:0x5637',
725+
function: 'MyClass::foo',
726+
in_app: true,
727+
},
728+
{
729+
filename: 'int) const (http://localhost:8001/main.wasm:wasm-function[190]:0x5aeb',
730+
function: 'MyClass::bar',
731+
in_app: true,
732+
},
733+
],
734+
},
735+
type: 'RuntimeError',
736+
value: 'memory access out of bounds',
737+
});
738+
});
646739
});

packages/nextjs/jest.config.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/nextjs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@
117117
"lint": "eslint . --format stylish",
118118
"test": "yarn test:unit",
119119
"test:all": "run-s test:unit",
120-
"test:unit": "jest",
121-
"test:watch": "jest --watch",
120+
"test:unit": "vitest run",
121+
"test:watch": "vitest --watch",
122122
"vercel:branch": "source vercel/set-up-branch-for-test-app-use.sh",
123123
"vercel:project": "source vercel/make-project-use-current-branch.sh",
124124
"yalc:publish": "yalc publish --push --sig"

packages/nextjs/rollup.npm.config.mjs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,22 @@ export default [
1818
// the name doesn't match an SDK dependency)
1919
packageSpecificConfig: {
2020
external: ['next/router', 'next/constants', 'next/headers', 'stacktrace-parser'],
21+
22+
// Next.js and our users are more happy when our client code has the "use client" directive
23+
plugins: [
24+
{
25+
name: 'sentry-internal-add-use-client-directive-to-client-entry-points-plugin-extravaganza',
26+
banner: chunk => {
27+
if (
28+
chunk.isEntry &&
29+
(chunk.facadeModuleId.endsWith('/src/index.client.ts') ||
30+
chunk.facadeModuleId.endsWith('/src/client/index.ts'))
31+
) {
32+
return '"use client";';
33+
}
34+
},
35+
},
36+
],
2137
},
2238
}),
2339
),

packages/nextjs/test/clientSdk.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import type { Integration } from '@sentry/core';
44
import * as SentryReact from '@sentry/react';
55
import { WINDOW, getClient, getCurrentScope } from '@sentry/react';
66
import { JSDOM } from 'jsdom';
7+
import { describe, vi, afterAll, afterEach, it, expect } from 'vitest';
78

89
import { breadcrumbsIntegration, browserTracingIntegration, init } from '../src/client';
910

10-
const reactInit = jest.spyOn(SentryReact, 'init');
11-
const loggerLogSpy = jest.spyOn(logger, 'log');
11+
const reactInit = vi.spyOn(SentryReact, 'init');
12+
const loggerLogSpy = vi.spyOn(logger, 'log');
1213

1314
// We're setting up JSDom here because the Next.js routing instrumentations requires a few things to be present on pageload:
1415
// 1. Access to window.document API for `window.document.getElementById`
@@ -38,7 +39,7 @@ const TEST_DSN = 'https://[email protected]/1337';
3839

3940
describe('Client init()', () => {
4041
afterEach(() => {
41-
jest.clearAllMocks();
42+
vi.clearAllMocks();
4243

4344
getGlobalScope().clear();
4445
getIsolationScope().clear();
@@ -83,7 +84,7 @@ describe('Client init()', () => {
8384
dsn: 'https://[email protected]/12312012',
8485
tracesSampleRate: 1.0,
8586
});
86-
const transportSend = jest.spyOn(getClient()!.getTransport()!, 'send');
87+
const transportSend = vi.spyOn(getClient()!.getTransport()!, 'send');
8788

8889
// Ensure we have no current span, so our next span is a transaction
8990
SentryReact.withActiveSpan(null, () => {

packages/nextjs/test/config/__snapshots__/valueInjectionLoader.test.ts.snap

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
// Jest Snapshot v1, https://goo.gl/fbAQLP
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3-
exports[`valueInjectionLoader should correctly insert values for basic config 1`] = `
3+
exports[`valueInjectionLoader > should correctly insert values for basic config 1`] = `
44
"
5-
;globalThis[\\"foo\\"] = \\"bar\\";import * as Sentry from '@sentry/nextjs';
5+
;globalThis["foo"] = "bar";import * as Sentry from '@sentry/nextjs';
66
Sentry.init();
77
"
88
`;
99

10-
exports[`valueInjectionLoader should correctly insert values with a misplaced directive 1`] = `
10+
exports[`valueInjectionLoader > should correctly insert values with a misplaced directive 1`] = `
1111
"
12-
;globalThis[\\"foo\\"] = \\"bar\\";console.log('This will render the directive useless');
13-
\\"use client\\";
12+
;globalThis["foo"] = "bar";console.log('This will render the directive useless');
13+
"use client";
1414
1515
1616
@@ -19,44 +19,44 @@ exports[`valueInjectionLoader should correctly insert values with a misplaced di
1919
"
2020
`;
2121

22-
exports[`valueInjectionLoader should correctly insert values with directive 1`] = `
22+
exports[`valueInjectionLoader > should correctly insert values with directive 1`] = `
2323
"
24-
\\"use client\\";globalThis[\\"foo\\"] = \\"bar\\";
24+
"use client";globalThis["foo"] = "bar";
2525
import * as Sentry from '@sentry/nextjs';
2626
Sentry.init();
2727
"
2828
`;
2929

30-
exports[`valueInjectionLoader should correctly insert values with directive and block comments 1`] = `
30+
exports[`valueInjectionLoader > should correctly insert values with directive and block comments 1`] = `
3131
"
3232
/* test */
33-
\\"use client\\";;globalThis[\\"foo\\"] = \\"bar\\";
33+
"use client";;globalThis["foo"] = "bar";
3434
import * as Sentry from '@sentry/nextjs';
3535
Sentry.init();
3636
"
3737
`;
3838

39-
exports[`valueInjectionLoader should correctly insert values with directive and inline comments 1`] = `
39+
exports[`valueInjectionLoader > should correctly insert values with directive and inline comments 1`] = `
4040
"
4141
// test
42-
\\"use client\\";;globalThis[\\"foo\\"] = \\"bar\\";
42+
"use client";;globalThis["foo"] = "bar";
4343
import * as Sentry from '@sentry/nextjs';
4444
Sentry.init();
4545
"
4646
`;
4747

48-
exports[`valueInjectionLoader should correctly insert values with directive and multiline block comments 1`] = `
48+
exports[`valueInjectionLoader > should correctly insert values with directive and multiline block comments 1`] = `
4949
"
5050
/*
5151
test
5252
*/
53-
\\"use client\\";;globalThis[\\"foo\\"] = \\"bar\\";
53+
"use client";;globalThis["foo"] = "bar";
5454
import * as Sentry from '@sentry/nextjs';
5555
Sentry.init();
5656
"
5757
`;
5858

59-
exports[`valueInjectionLoader should correctly insert values with directive and multiline block comments and a bunch of whitespace 1`] = `
59+
exports[`valueInjectionLoader > should correctly insert values with directive and multiline block comments and a bunch of whitespace 1`] = `
6060
"
6161
/*
6262
test
@@ -65,7 +65,7 @@ exports[`valueInjectionLoader should correctly insert values with directive and
6565
6666
6767
68-
\\"use client\\";;globalThis[\\"foo\\"] = \\"bar\\";
68+
"use client";;globalThis["foo"] = "bar";
6969
7070
7171
@@ -74,9 +74,9 @@ exports[`valueInjectionLoader should correctly insert values with directive and
7474
"
7575
`;
7676

77-
exports[`valueInjectionLoader should correctly insert values with directive and semicolon 1`] = `
77+
exports[`valueInjectionLoader > should correctly insert values with directive and semicolon 1`] = `
7878
"
79-
\\"use client\\";;globalThis[\\"foo\\"] = \\"bar\\";
79+
"use client";;globalThis["foo"] = "bar";
8080
import * as Sentry from '@sentry/nextjs';
8181
Sentry.init();
8282
"

packages/nextjs/test/config/loaders.test.ts

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import './mocks';
33

44
import * as fs from 'fs';
5+
import { describe, vi, it, expect } from 'vitest';
56

67
import type { ModuleRuleUseProperty, WebpackModuleRule } from '../../src/config/types';
78
import {
@@ -13,36 +14,8 @@ import {
1314
} from './fixtures';
1415
import { materializeFinalWebpackConfig } from './testUtils';
1516

16-
const existsSyncSpy = jest.spyOn(fs, 'existsSync');
17-
const lstatSyncSpy = jest.spyOn(fs, 'lstatSync');
18-
19-
type MatcherResult = { pass: boolean; message: () => string };
20-
21-
expect.extend({
22-
stringEndingWith(received: string, expectedEnding: string): MatcherResult {
23-
const failsTest = !received.endsWith(expectedEnding);
24-
const generateErrorMessage = () =>
25-
failsTest
26-
? // Regular error message for match failing
27-
`expected string ending with '${expectedEnding}', but got '${received}'`
28-
: // Error message for the match passing if someone has called it with `expect.not`
29-
`expected string not ending with '${expectedEnding}', but got '${received}'`;
30-
31-
return {
32-
pass: !failsTest,
33-
message: generateErrorMessage,
34-
};
35-
},
36-
});
37-
38-
declare global {
39-
// eslint-disable-next-line @typescript-eslint/no-namespace
40-
namespace jest {
41-
interface Expect {
42-
stringEndingWith: (expectedEnding: string) => MatcherResult;
43-
}
44-
}
45-
}
17+
const existsSyncSpy = vi.spyOn(fs, 'existsSync');
18+
const lstatSyncSpy = vi.spyOn(fs, 'lstatSync');
4619

4720
function applyRuleToResource(rule: WebpackModuleRule, resourcePath: string): ModuleRuleUseProperty[] {
4821
const applications = [];
@@ -80,7 +53,7 @@ describe('webpack loaders', () => {
8053
test: expect.any(RegExp),
8154
use: [
8255
{
83-
loader: expect.stringEndingWith('valueInjectionLoader.js'),
56+
loader: expect.stringMatching(/valueInjectionLoader\.js$/),
8457
// We use `expect.objectContaining({})` rather than `expect.any(Object)` to match any plain object because
8558
// the latter will also match arrays, regexes, dates, sets, etc. - anything whose `typeof` value is
8659
// `'object'`.
@@ -272,7 +245,7 @@ describe('webpack loaders', () => {
272245
test: /sentry\.client\.config\.(jsx?|tsx?)/,
273246
use: [
274247
{
275-
loader: expect.stringEndingWith('valueInjectionLoader.js'),
248+
loader: expect.stringMatching(/valueInjectionLoader\.js$/),
276249
// We use `expect.objectContaining({})` rather than `expect.any(Object)` to match any plain object because
277250
// the latter will also match arrays, regexes, dates, sets, etc. - anything whose `typeof` value is
278251
// `'object'`.
@@ -285,9 +258,10 @@ describe('webpack loaders', () => {
285258
});
286259

287260
describe('`distDir` value in default server-side `RewriteFrames` integration', () => {
288-
describe('`RewriteFrames` ends up with correct `distDir` value', () => {
261+
it('`RewriteFrames` ends up with correct `distDir` value', () => {
289262
// TODO: this, along with any number of other parts of the build process, should be tested with an integration
290263
// test which actually runs webpack and inspects the resulting bundles (and that integration test should test
291-
// custom `distDir` values with and without a `.`, to make sure the regex escaping is working)
264+
// custom `distDir` values with and without a `.`, to make sure the regex
265+
// escaping is working)
292266
});
293267
});

0 commit comments

Comments
 (0)