Skip to content

meta: Add CHANGELOG entry for 8.5.0 #12236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a87af78
Merge pull request #12195 from getsentry/master
github-actions[bot] May 23, 2024
a9e6ba8
fix(node): Add origin to redis span (#12201)
mydea May 24, 2024
0ac519a
chore(ci): Remove unused NODE_VERSION 16 env from browser ci tests (#…
andreiborza May 24, 2024
a9cef35
fix(browser): Remove optional chaining in INP code (#12196)
AbhiPrasad May 24, 2024
41951ba
fix(nextjs): Don't report React postpone errors (#12194)
May 24, 2024
805c577
build(react/remix): Use new `jsx` JSX transform instead of `React.cre…
May 24, 2024
ca4afef
feat(react): Add React 19 to peer deps (#12207)
AbhiPrasad May 24, 2024
5791a38
fix(replay): Update matcher for hydration error detection to new Reac…
May 24, 2024
3ea5373
fix(nextjs): Use global scope for generic event filters (#12205)
May 24, 2024
93c467d
test: Disable ember-release and embroider-optimized ember canary test…
AbhiPrasad May 24, 2024
186e982
feat(solidjs): Add solidjs SDK basic package (#12193)
andreiborza May 24, 2024
8fa393c
fix(node): Change import of `@prisma/instrumentation` to use default …
May 24, 2024
cc1cb7b
feat(node): Ensure manual OTEL setup works (#12214)
mydea May 27, 2024
5a1fae6
feat(core): Allow to pass custom scope to `captureFeedback()` (#12216)
mydea May 27, 2024
330750d
feat(core): Add `startNewTrace` API (#12138)
Lms24 May 27, 2024
b188e61
feat(node): Add `@sentry/node/preload` hook (#12213)
mydea May 27, 2024
5469f89
feat(lforst): Only allow `SerializedSession` in session envelope item…
May 27, 2024
8479698
build: Add size-limit entry for metrics (#12227)
mydea May 27, 2024
3e179e1
test(e2e): Unflake sveltekit test (#12228)
May 27, 2024
2043f2d
feat(nextjs): Use Vercel's `waitUntil` to defer freezing of Vercel La…
May 27, 2024
c2b9079
fix(aws-serverless): Avoid minifying `Module._resolveFilename` in Lam…
Lms24 May 27, 2024
1f8f1b8
ref(profiling-node): Add warning when using non-LTS node (#12211)
AbhiPrasad May 27, 2024
5282753
fix: Only import `inspector` asynchronously (#12231)
timfish May 27, 2024
83c255a
fix(aws): Ensure lambda layer uses default export from `ImportInTheMi…
Lms24 May 27, 2024
8dca102
fix(browser): Improve browser extension error message check (#12146)
Lms24 May 27, 2024
0fbe39a
feat(browser): Do not include metrics in base CDN bundle (#12230)
mydea May 27, 2024
f32f88d
meta: Add CHANGELOG entry for `8.5.0`
Lms24 May 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -436,8 +436,6 @@ jobs:
env:
DEPENDENCY_CACHE_KEY: ${{ needs.job_build.outputs.dependency_cache_key }}
- name: Run tests
env:
NODE_VERSION: 16
run: yarn test-ci-browser
- name: Compute test coverage
uses: codecov/codecov-action@v4
Expand Down Expand Up @@ -1005,7 +1003,9 @@ jobs:
'create-remix-app-express-vite-dev',
'debug-id-sourcemaps',
'node-express-esm-loader',
'node-express-esm-preload',
'node-express-esm-without-loader',
'node-express-cjs-preload',
'nextjs-app-dir',
'nextjs-14',
'nextjs-15',
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ jobs:
strategy:
fail-fast: false
matrix:
scenario: [ember-release, embroider-optimized, ember-4.0]
# scenario: [ember-release, embroider-optimized, ember-4.0]
scenario: [ember-4.0]
steps:
- name: 'Check out current commit'
uses: actions/checkout@v4
Expand Down
16 changes: 16 additions & 0 deletions .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ module.exports = [
gzip: true,
limit: '87 KB',
},
{
name: '@sentry/browser (incl. Tracing, Replay, Feedback, metrics)',
path: 'packages/browser/build/npm/esm/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration', 'metrics'),
gzip: true,
limit: '100 KB',
},
{
name: '@sentry/browser (incl. metrics)',
path: 'packages/browser/build/npm/esm/index.js',
import: createImport('init', 'metrics'),
gzip: true,
limit: '40 KB',
},
{
name: '@sentry/browser (incl. Feedback)',
path: 'packages/browser/build/npm/esm/index.js',
Expand All @@ -83,13 +97,15 @@ module.exports = [
name: '@sentry/react',
path: 'packages/react/build/esm/index.js',
import: createImport('init', 'ErrorBoundary'),
ignore: ['react/jsx-runtime'],
gzip: true,
limit: '27 KB',
},
{
name: '@sentry/react (incl. Tracing)',
path: 'packages/react/build/esm/index.js',
import: createImport('init', 'ErrorBoundary', 'reactRouterV6BrowserTracingIntegration'),
ignore: ['react/jsx-runtime'],
gzip: true,
limit: '37 KB',
},
Expand Down
53 changes: 53 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,59 @@

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

## 8.5.0

### Important Changes

- **feat(react): Add React 19 to peer deps (#12207)**

This release adds support for React 19 in the `@sentry/react` SDK package.

- **feat(node): Add `@sentry/node/preload` hook (#12213)**

This release adds a new way to initialize `@sentry/node`, which allows you to use the SDK with performance
instrumentation even if you cannot call `Sentry.init()` at the very start of your app.

First, run the SDK like this:

```bash
node --require @sentry/node/preload ./app.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
node --require @sentry/node/preload ./app.js
node --import @sentry/node/preload ./app.mjs

not 100% sure, should we use the cjs or esm example here? 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess CJS is probably fine, thinking about this... so disregard this comment I guess!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I asked myself the same thing 😅 I guess CJS is still used more frequently so... 🤷
Basically I wanted to add a small snippet to show the use case but not copy the entire PR description.

```

Now, you can initialize and import the rest of the SDK later or asynchronously:

```js
const express = require('express');
const Sentry = require('@sentry/node');

const dsn = await getSentryDsn();
Sentry.init({ dsn });
```

For more details, head over to the
[PR Description of the new feature](https://github.com/getsentry/sentry-javascript/pull/12213). Our docs will be updated
soon with a new guide.

### Other Changes

- feat(browser): Do not include metrics in base CDN bundle (#12230)
- feat(core): Add `startNewTrace` API (#12138)
- feat(core): Allow to pass custom scope to `captureFeedback()` (#12216)
- feat(core): Only allow `SerializedSession` in session envelope items (#11979)
- feat(nextjs): Use Vercel's `waitUntil` to defer freezing of Vercel Lambdas (#12133)
- feat(node): Ensure manual OTEL setup works (#12214)
- fix(aws-serverless): Avoid minifying `Module._resolveFilename` in Lambda layer bundle (#12232)
- fix(aws-serverless): Ensure lambda layer uses default export from `ImportInTheMiddle` (#12233)
- fix(browser): Improve browser extension error message check (#12146)
- fix(browser): Remove optional chaining in INP code (#12196)
- fix(nextjs): Don't report React postpone errors (#12194)
- fix(nextjs): Use global scope for generic event filters (#12205)
- fix(node): Add origin to redis span (#12201)
- fix(node): Change import of `@prisma/instrumentation` to use default import (#12185)
- fix(node): Only import `inspector` asynchronously (#12231)
- fix(replay): Update matcher for hydration error detection to new React docs (#12209)
- ref(profiling-node): Add warning when using non-LTS node (#12211)

## 8.4.0

### Important Changes
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../utils/fixtures';
import { getFirstSentryEnvelopeRequest, properEnvelopeRequestParser } from '../../utils/helpers';
import { sentryTest } from '../../../utils/fixtures';
import {
getFirstSentryEnvelopeRequest,
properEnvelopeRequestParser,
shouldSkipMetricsTest,
} from '../../../utils/helpers';

sentryTest('collects metrics', async ({ getLocalTestUrl, page }) => {
if (shouldSkipMetricsTest()) {
sentryTest.skip();
}

const url = await getLocalTestUrl({ testDir: __dirname });

const statsdBuffer = await getFirstSentryEnvelopeRequest<Uint8Array>(page, url, properEnvelopeRequestParser);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
});

// This should not fail
Sentry.metrics.increment('increment');
Sentry.metrics.distribution('distribution', 42);
Sentry.metrics.gauge('gauge', 5);
Sentry.metrics.set('set', 'nope');
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../../utils/fixtures';
import { shouldSkipMetricsTest } from '../../../utils/helpers';

sentryTest('exports shim metrics integration for non-tracing bundles', async ({ getLocalTestPath, page }) => {
// Skip in tracing tests
if (!shouldSkipMetricsTest()) {
sentryTest.skip();
}

const consoleMessages: string[] = [];
page.on('console', msg => consoleMessages.push(msg.text()));

let requestCount = 0;
await page.route('https://dsn.ingest.sentry.io/**/*', route => {
requestCount++;
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ id: 'test-id' }),
});
});

const url = await getLocalTestPath({ testDir: __dirname });

await page.goto(url);

expect(requestCount).toBe(0);
expect(consoleMessages).toEqual([
'You are using metrics even though this bundle does not include tracing.',
'You are using metrics even though this bundle does not include tracing.',
'You are using metrics even though this bundle does not include tracing.',
'You are using metrics even though this bundle does not include tracing.',
]);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const newTraceBtn = document.getElementById('newTrace');
newTraceBtn.addEventListener('click', async () => {
Sentry.startNewTrace(() => {
Sentry.startSpan({ op: 'ui.interaction.click', name: 'new-trace' }, async () => {
await fetch('http://example.com');
});
});
});

const oldTraceBtn = document.getElementById('oldTrace');
oldTraceBtn.addEventListener('click', async () => {
Sentry.startSpan({ op: 'ui.interaction.click', name: 'old-trace' }, async () => {
await fetch('http://example.com');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<button id="oldTrace">Old Trace</button>
<button id="newTrace">new Trace</button>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { expect } from '@playwright/test';
import { sentryTest } from '../../../../utils/fixtures';
import type { EventAndTraceHeader } from '../../../../utils/helpers';
import {
eventAndTraceHeaderRequestParser,
getFirstSentryEnvelopeRequest,
getMultipleSentryEnvelopeRequests,
shouldSkipTracingTest,
} from '../../../../utils/helpers';

sentryTest(
'creates a new trace if `startNewTrace` is called and leaves old trace valid outside the callback',
async ({ getLocalTestUrl, page }) => {
if (shouldSkipTracingTest()) {
sentryTest.skip();
}

const url = await getLocalTestUrl({ testDir: __dirname });

await page.route('http://example.com/**', route => {
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({}),
});
});

const [pageloadEvent, pageloadTraceHeaders] = await getFirstSentryEnvelopeRequest<EventAndTraceHeader>(
page,
url,
eventAndTraceHeaderRequestParser,
);

const pageloadTraceContext = pageloadEvent.contexts?.trace;

expect(pageloadEvent.type).toEqual('transaction');

expect(pageloadTraceContext).toMatchObject({
op: 'pageload',
trace_id: expect.stringMatching(/^[0-9a-f]{32}$/),
span_id: expect.stringMatching(/^[0-9a-f]{16}$/),
});
expect(pageloadTraceContext).not.toHaveProperty('parent_span_id');

expect(pageloadTraceHeaders).toEqual({
environment: 'production',
public_key: 'public',
sample_rate: '1',
sampled: 'true',
trace_id: pageloadTraceContext?.trace_id,
});

const transactionPromises = getMultipleSentryEnvelopeRequests<EventAndTraceHeader>(
page,
2,
{ envelopeType: 'transaction' },
eventAndTraceHeaderRequestParser,
);

await page.locator('#newTrace').click();
await page.locator('#oldTrace').click();

const [txnEvent1, txnEvent2] = await transactionPromises;

const [newTraceTransactionEvent, newTraceTransactionTraceHeaders] =
txnEvent1[0].transaction === 'new-trace' ? txnEvent1 : txnEvent2;
const [oldTraceTransactionEvent, oldTraceTransactionTraceHeaders] =
txnEvent1[0].transaction === 'old-trace' ? txnEvent1 : txnEvent2;

const newTraceTransactionTraceContext = newTraceTransactionEvent.contexts?.trace;
expect(newTraceTransactionTraceContext).toMatchObject({
op: 'ui.interaction.click',
trace_id: expect.stringMatching(/^[0-9a-f]{32}$/),
span_id: expect.stringMatching(/^[0-9a-f]{16}$/),
});

expect(newTraceTransactionTraceHeaders).toEqual({
environment: 'production',
public_key: 'public',
sample_rate: '1',
sampled: 'true',
trace_id: newTraceTransactionTraceContext?.trace_id,
transaction: 'new-trace',
});

const oldTraceTransactionEventTraceContext = oldTraceTransactionEvent.contexts?.trace;
expect(oldTraceTransactionEventTraceContext).toMatchObject({
op: 'ui.interaction.click',
trace_id: expect.stringMatching(/^[0-9a-f]{32}$/),
span_id: expect.stringMatching(/^[0-9a-f]{16}$/),
});

expect(oldTraceTransactionTraceHeaders).toEqual({
environment: 'production',
public_key: 'public',
sample_rate: '1',
sampled: 'true',
trace_id: oldTraceTransactionTraceHeaders?.trace_id,
// transaction: 'old-trace', <-- this is not in the DSC because the DSC is continued from the pageload transaction
// which does not have a `transaction` field because its source is URL.
});

expect(oldTraceTransactionEventTraceContext?.trace_id).toEqual(pageloadTraceContext?.trace_id);
expect(newTraceTransactionTraceContext?.trace_id).not.toEqual(pageloadTraceContext?.trace_id);
},
);
14 changes: 13 additions & 1 deletion dev-packages/browser-integration-tests/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export function shouldSkipTracingTest(): boolean {
}

/**
* We can only test replay tests in certain bundles/packages:
* We can only test feedback tests in certain bundles/packages:
* - NPM (ESM, CJS)
* - CDN bundles that contain the Replay integration
*
Expand All @@ -252,6 +252,18 @@ export function shouldSkipFeedbackTest(): boolean {
return bundle != null && !bundle.includes('feedback') && !bundle.includes('esm') && !bundle.includes('cjs');
}

/**
* We can only test metrics tests in certain bundles/packages:
* - NPM (ESM, CJS)
* - CDN bundles that include tracing
*
* @returns `true` if we should skip the metrics test
*/
export function shouldSkipMetricsTest(): boolean {
const bundle = process.env.PW_BUNDLE as string | undefined;
return bundle != null && !bundle.includes('tracing') && !bundle.includes('esm') && !bundle.includes('cjs');
}

/**
* Waits until a number of requests matching urlRgx at the given URL arrive.
* If the timout option is configured, this function will abort waiting, even if it hasn't reveived the configured
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as Sentry from '@sentry/nextjs';

export default async function Page({
searchParams,
}: {
searchParams: { id?: string };
}) {
try {
console.log(searchParams.id); // Accessing a field on searchParams will throw the PPR error
} catch (e) {
Sentry.captureException(e); // This error should not be reported
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for any async event processors to run
await Sentry.flush();
throw e;
}

return <div>This server component will throw a PPR error that we do not want to catch.</div>;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
const { withSentryConfig } = require('@sentry/nextjs');

/** @type {import('next').NextConfig} */
const nextConfig = {};
const nextConfig = {
experimental: {
ppr: true,
},
};

module.exports = withSentryConfig(nextConfig, {
silent: true,
Expand Down
Loading
Loading