Skip to content

Commit 0a9387a

Browse files
authored
Merge branch 'develop' into jb/pkg/profiling-node
2 parents 32b0c61 + 7dc9260 commit 0a9387a

File tree

206 files changed

+4026
-724
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

206 files changed

+4026
-724
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,8 @@ jobs:
974974
'generic-ts3.8',
975975
'node-experimental-fastify-app',
976976
'node-hapi-app',
977-
'node-profiling'
977+
'node-profiling',
978+
'node-exports-test-app',
978979
]
979980
build-command:
980981
- false

.size-limit.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ module.exports = [
4747
gzip: true,
4848
limit: '35 KB',
4949
},
50+
{
51+
name: '@sentry/browser (incl. browserTracingIntegration) - Webpack (gzipped)',
52+
path: 'packages/browser/build/npm/esm/index.js',
53+
import: '{ init, browserTracingIntegration }',
54+
gzip: true,
55+
limit: '35 KB',
56+
},
5057
{
5158
name: '@sentry/browser (incl. Feedback) - Webpack (gzipped)',
5259
path: 'packages/browser/build/npm/esm/index.js',

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ finished. This is useful for event emitters or similar.
11031103
function middleware(_req, res, next) {
11041104
return Sentry.startSpanManual({ name: 'middleware' }, (span, finish) => {
11051105
res.once('finish', () => {
1106-
span?.setHttpStatus(res.status);
1106+
setHttpStatus(span, res.status);
11071107
finish();
11081108
});
11091109
return next();

CONTRIBUTING.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ able to use it. From the top level of the repo, there are three commands availab
3737
dependencies (`utils`, `core`, `browser`, etc), and all packages which depend on it (currently `gatsby` and `nextjs`))
3838
- `yarn build:dev:watch`, which runs `yarn build:dev` in watch mode (recommended)
3939

40+
You can also run a production build via `yarn build`, which will build everything except for the tarballs for publishing
41+
to NPM. You can use this if you want to bundle Sentry yourself. The build output can be found in the packages `build/`
42+
folder, e.g. `packages/browser/build`. Bundled files can be found in `packages/browser/build/bundles`. Note that there
43+
are no guarantees about the produced file names etc., so make sure to double check which files are generated after
44+
upgrading.
45+
4046
## Testing SDK Packages Locally
4147

4248
To test local versions of SDK packages, for instance in test projects, you have a couple of options:

MIGRATION.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,15 @@ The following list shows how integrations should be migrated:
5353
| `new RewriteFrames()` | `rewriteFramesIntegration()` | `@sentry/integrations` |
5454
| `new SessionTiming()` | `sessionTimingIntegration()` | `@sentry/integrations` |
5555
| `new HttpClient()` | `httpClientIntegration()` | `@sentry/integrations` |
56-
| `new ContextLines()` | `contextLinesIntegration()` | `@sentry/browser` |
56+
| `new ContextLines()` | `contextLinesIntegration()` | `@sentry/browser`, `@sentry/deno` |
5757
| `new Breadcrumbs()` | `breadcrumbsIntegration()` | `@sentry/browser`, `@sentry/deno` |
58-
| `new GlobalHandlers()` | `globalHandlersIntegration()` | `@sentry/browser` |
58+
| `new GlobalHandlers()` | `globalHandlersIntegration()` | `@sentry/browser` , `@sentry/deno` |
5959
| `new HttpContext()` | `httpContextIntegration()` | `@sentry/browser` |
6060
| `new TryCatch()` | `browserApiErrorsIntegration()` | `@sentry/browser`, `@sentry/deno` |
6161
| `new VueIntegration()` | `vueIntegration()` | `@sentry/vue` |
62+
| `new DenoContext()` | `denoContextIntegration()` | `@sentry/deno` |
63+
| `new DenoCron()` | `denoCronIntegration()` | `@sentry/deno` |
64+
| `new NormalizePaths()` | `normalizePathsIntegration()` | `@sentry/deno` |
6265

6366
## Deprecate `hub.bindClient()` and `makeMain()`
6467

biome.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,12 @@
4747
"dev-packages/browser-integration-tests/suites/**/*.json",
4848
"dev-packages/browser-integration-tests/loader-suites/**/*.js",
4949
"dev-packages/browser-integration-tests/suites/stacktraces/**/*.js",
50+
".next/**/*",
5051
"**/fixtures/*/*.json",
5152
"**/*.min.js",
5253
"**/profiling-node/lib/**"
54+
".next/**",
55+
".svelte-kit/**"
5356
]
5457
},
5558
"javascript": {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
// Replay should not actually work, but still not error out
6+
window.Replay = new Sentry.replayIntegration({
7+
flushMinDelay: 200,
8+
flushMaxDelay: 200,
9+
minReplayDuration: 0,
10+
});
11+
12+
Sentry.init({
13+
dsn: 'https://[email protected]/1337',
14+
sampleRate: 1,
15+
replaysSessionSampleRate: 1.0,
16+
replaysOnErrorSampleRate: 0.0,
17+
integrations: [window.Replay],
18+
});
19+
20+
// Ensure none of these break
21+
window.Replay.start();
22+
window.Replay.stop();
23+
window.Replay.flush();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<button onclick="console.log('Test log')">Click me</button>
8+
</body>
9+
</html>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { expect } from '@playwright/test';
2+
3+
import { sentryTest } from '../../../utils/fixtures';
4+
5+
sentryTest(
6+
'exports a shim replayIntegration integration for non-replay bundles',
7+
async ({ getLocalTestPath, page, forceFlushReplay }) => {
8+
const bundle = process.env.PW_BUNDLE;
9+
10+
if (!bundle || !bundle.startsWith('bundle_') || bundle.includes('replay')) {
11+
sentryTest.skip();
12+
}
13+
14+
const consoleMessages: string[] = [];
15+
page.on('console', msg => consoleMessages.push(msg.text()));
16+
17+
let requestCount = 0;
18+
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
19+
requestCount++;
20+
return route.fulfill({
21+
status: 200,
22+
contentType: 'application/json',
23+
body: JSON.stringify({ id: 'test-id' }),
24+
});
25+
});
26+
27+
const url = await getLocalTestPath({ testDir: __dirname });
28+
29+
await page.goto(url);
30+
await forceFlushReplay();
31+
32+
expect(requestCount).toBe(0);
33+
expect(consoleMessages).toEqual(['You are using new Replay() even though this bundle does not include replay.']);
34+
},
35+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
integrations: [Sentry.browserTracingIntegration({ idleTimeout: 9000 })],
8+
tracesSampleRate: 1,
9+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
document.getElementById('go-background').addEventListener('click', () => {
2+
Object.defineProperty(document, 'hidden', { value: true, writable: true });
3+
const ev = document.createEvent('Event');
4+
ev.initEvent('visibilitychange');
5+
document.dispatchEvent(ev);
6+
});
7+
8+
document.getElementById('start-transaction').addEventListener('click', () => {
9+
window.transaction = Sentry.startTransaction({ name: 'test-transaction' });
10+
Sentry.getCurrentHub().configureScope(scope => scope.setSpan(window.transaction));
11+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<button id="start-transaction">Start Transaction</button>
8+
<button id="go-background">New Tab</button>
9+
</body>
10+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { JSHandle } from '@playwright/test';
2+
import { expect } from '@playwright/test';
3+
import type { Event } from '@sentry/types';
4+
5+
import { sentryTest } from '../../../../utils/fixtures';
6+
import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';
7+
8+
async function getPropertyValue(handle: JSHandle, prop: string) {
9+
return (await handle.getProperty(prop))?.jsonValue();
10+
}
11+
12+
sentryTest('should finish a custom transaction when the page goes background', async ({ getLocalTestPath, page }) => {
13+
if (shouldSkipTracingTest()) {
14+
sentryTest.skip();
15+
}
16+
17+
const url = await getLocalTestPath({ testDir: __dirname });
18+
19+
const pageloadTransaction = await getFirstSentryEnvelopeRequest<Event>(page, url);
20+
expect(pageloadTransaction).toBeDefined();
21+
22+
await page.locator('#start-transaction').click();
23+
const transactionHandle = await page.evaluateHandle('window.transaction');
24+
25+
const id_before = await getPropertyValue(transactionHandle, 'span_id');
26+
const name_before = await getPropertyValue(transactionHandle, 'name');
27+
const status_before = await getPropertyValue(transactionHandle, 'status');
28+
const tags_before = await getPropertyValue(transactionHandle, 'tags');
29+
30+
expect(name_before).toBe('test-transaction');
31+
expect(status_before).toBeUndefined();
32+
expect(tags_before).toStrictEqual({});
33+
34+
await page.locator('#go-background').click();
35+
36+
const id_after = await getPropertyValue(transactionHandle, 'span_id');
37+
const name_after = await getPropertyValue(transactionHandle, 'name');
38+
const status_after = await getPropertyValue(transactionHandle, 'status');
39+
const tags_after = await getPropertyValue(transactionHandle, 'tags');
40+
41+
expect(id_before).toBe(id_after);
42+
expect(name_after).toBe(name_before);
43+
expect(status_after).toBe('cancelled');
44+
expect(tags_after).toStrictEqual({ visibilitychange: 'document.hidden' });
45+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
document.getElementById('go-background').addEventListener('click', () => {
2+
setTimeout(() => {
3+
Object.defineProperty(document, 'hidden', { value: true, writable: true });
4+
const ev = document.createEvent('Event');
5+
ev.initEvent('visibilitychange');
6+
document.dispatchEvent(ev);
7+
}, 250);
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
</head>
6+
<body>
7+
<button id="go-background">New Tab</button>
8+
</body>
9+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { expect } from '@playwright/test';
2+
import type { Event } from '@sentry/types';
3+
4+
import { sentryTest } from '../../../../utils/fixtures';
5+
import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';
6+
7+
sentryTest('should finish pageload transaction when the page goes background', async ({ getLocalTestPath, page }) => {
8+
if (shouldSkipTracingTest()) {
9+
sentryTest.skip();
10+
}
11+
const url = await getLocalTestPath({ testDir: __dirname });
12+
13+
await page.goto(url);
14+
await page.locator('#go-background').click();
15+
16+
const pageloadTransaction = await getFirstSentryEnvelopeRequest<Event>(page);
17+
18+
expect(pageloadTransaction.contexts?.trace?.op).toBe('pageload');
19+
expect(pageloadTransaction.contexts?.trace?.status).toBe('cancelled');
20+
expect(pageloadTransaction.contexts?.trace?.tags).toMatchObject({
21+
visibilitychange: 'document.hidden',
22+
});
23+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
integrations: [
8+
Sentry.browserTracingIntegration({
9+
idleTimeout: 1000,
10+
_experiments: {
11+
enableHTTPTimings: true,
12+
},
13+
}),
14+
],
15+
tracesSampleRate: 1,
16+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fetch('http://example.com/0').then(fetch('http://example.com/1').then(fetch('http://example.com/2')));
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { expect } from '@playwright/test';
2+
import type { SerializedEvent } from '@sentry/types';
3+
4+
import { sentryTest } from '../../../../utils/fixtures';
5+
import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers';
6+
7+
sentryTest('should create fetch spans with http timing @firefox', async ({ browserName, getLocalTestPath, page }) => {
8+
const supportedBrowsers = ['chromium', 'firefox'];
9+
10+
if (shouldSkipTracingTest() || !supportedBrowsers.includes(browserName)) {
11+
sentryTest.skip();
12+
}
13+
await page.route('http://example.com/*', async route => {
14+
const request = route.request();
15+
const postData = await request.postDataJSON();
16+
17+
await route.fulfill({
18+
status: 200,
19+
contentType: 'application/json',
20+
body: JSON.stringify(Object.assign({ id: 1 }, postData)),
21+
});
22+
});
23+
24+
const url = await getLocalTestPath({ testDir: __dirname });
25+
26+
const envelopes = await getMultipleSentryEnvelopeRequests<SerializedEvent>(page, 2, { url, timeout: 10000 });
27+
const tracingEvent = envelopes[envelopes.length - 1]; // last envelope contains tracing data on all browsers
28+
29+
// eslint-disable-next-line deprecation/deprecation
30+
const requestSpans = tracingEvent.spans?.filter(({ op }) => op === 'http.client');
31+
32+
expect(requestSpans).toHaveLength(3);
33+
34+
await page.pause();
35+
requestSpans?.forEach((span, index) =>
36+
expect(span).toMatchObject({
37+
description: `GET http://example.com/${index}`,
38+
parent_span_id: tracingEvent.contexts?.trace?.span_id,
39+
span_id: expect.any(String),
40+
start_timestamp: expect.any(Number),
41+
timestamp: expect.any(Number),
42+
trace_id: tracingEvent.contexts?.trace?.trace_id,
43+
data: expect.objectContaining({
44+
'http.request.redirect_start': expect.any(Number),
45+
'http.request.fetch_start': expect.any(Number),
46+
'http.request.domain_lookup_start': expect.any(Number),
47+
'http.request.domain_lookup_end': expect.any(Number),
48+
'http.request.connect_start': expect.any(Number),
49+
'http.request.secure_connection_start': expect.any(Number),
50+
'http.request.connection_end': expect.any(Number),
51+
'http.request.request_start': expect.any(Number),
52+
'http.request.response_start': expect.any(Number),
53+
'http.request.response_end': expect.any(Number),
54+
'network.protocol.version': expect.any(String),
55+
}),
56+
}),
57+
);
58+
});
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
integrations: [Sentry.browserTracingIntegration()],
8+
tracesSampleRate: 1,
9+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const delay = e => {
2+
const startTime = Date.now();
3+
4+
function getElasped() {
5+
const time = Date.now();
6+
return time - startTime;
7+
}
8+
9+
while (getElasped() < 70) {
10+
//
11+
}
12+
13+
e.target.classList.add('clicked');
14+
};
15+
16+
document.querySelector('[data-test-id=interaction-button]').addEventListener('click', delay);
17+
document.querySelector('[data-test-id=annotated-button]').addEventListener('click', delay);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import * as Sentry from '@sentry/browser';
2+
3+
window.Sentry = Sentry;
4+
5+
Sentry.init({
6+
dsn: 'https://[email protected]/1337',
7+
integrations: [
8+
Sentry.browserTracingIntegration({
9+
idleTimeout: 1000,
10+
enableLongTask: false,
11+
_experiments: {
12+
enableInteractions: true,
13+
},
14+
}),
15+
],
16+
tracesSampleRate: 1,
17+
});

0 commit comments

Comments
 (0)