Skip to content

Commit

Permalink
Merge pull request #14244 from getsentry/prepare-release/8.38.0
Browse files Browse the repository at this point in the history
meta(changelog): Update changelog for 8.38.0
  • Loading branch information
andreiborza authored Nov 12, 2024
2 parents d7ed9d3 + ad1f938 commit 9a98d98
Show file tree
Hide file tree
Showing 90 changed files with 2,001 additions and 372 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/external-contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ jobs:
# This token is scoped to Daniel Griesser
# If we used the default GITHUB_TOKEN, the resulting PR would not trigger CI :(
token: ${{ secrets.REPO_SCOPED_TOKEN }}
commit-message: "ref: Add external contributor to CHANGELOG.md"
title: "ref: Add external contributor to CHANGELOG.md"
commit-message: "chore: Add external contributor to CHANGELOG.md"
title: "chore: Add external contributor to CHANGELOG.md"
branch: 'external-contributor/patch-${{ github.event.pull_request.user.login }}'
base: 'develop'
delete-branch: true
Expand Down
2 changes: 1 addition & 1 deletion .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ module.exports = [
path: 'packages/browser/build/npm/esm/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'replayCanvasIntegration'),
gzip: true,
limit: '78.1 KB',
limit: '78.2 KB',
},
{
name: '@sentry/browser (incl. Tracing, Replay, Feedback)',
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@

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

## 8.38.0

- docs: Improve docstrings for node otel integrations ([#14217](https://github.com/getsentry/sentry-javascript/pull/14217))
- feat(browser): Add moduleMetadataIntegration lazy loading support ([#13817](https://github.com/getsentry/sentry-javascript/pull/13817))
- feat(core): Add trpc path to context in trpcMiddleware ([#14218](https://github.com/getsentry/sentry-javascript/pull/14218))
- feat(deps): Bump @opentelemetry/instrumentation-amqplib from 0.42.0 to 0.43.0 ([#14230](https://github.com/getsentry/sentry-javascript/pull/14230))
- feat(deps): Bump @sentry/cli from 2.37.0 to 2.38.2 ([#14232](https://github.com/getsentry/sentry-javascript/pull/14232))
- feat(node): Add `knex` integration ([#13526](https://github.com/getsentry/sentry-javascript/pull/13526))
- feat(node): Add `tedious` integration ([#13486](https://github.com/getsentry/sentry-javascript/pull/13486))
- feat(utils): Single implementation to fetch debug ids ([#14199](https://github.com/getsentry/sentry-javascript/pull/14199))
- fix(browser): Avoid recording long animation frame spans starting before their parent span ([#14186](https://github.com/getsentry/sentry-javascript/pull/14186))
- fix(node): Include `debug_meta` with ANR events ([#14203](https://github.com/getsentry/sentry-javascript/pull/14203))
- fix(nuxt): Fix dynamic import rollup plugin to work with latest nitro ([#14243](https://github.com/getsentry/sentry-javascript/pull/14243))
- fix(react): Support wildcard routes on React Router 6 ([#14205](https://github.com/getsentry/sentry-javascript/pull/14205))
- fix(spotlight): Export spotlightBrowserIntegration from the main browser package ([#14208](https://github.com/getsentry/sentry-javascript/pull/14208))
- ref(browser): Ensure start time of interaction root and child span is aligned ([#14188](https://github.com/getsentry/sentry-javascript/pull/14188))
- ref(nextjs): Make build-time value injection turbopack compatible ([#14081](https://github.com/getsentry/sentry-javascript/pull/14081))

Work in this release was contributed by @grahamhency, @Zen-cronic, @gilisho and @phuctm97. Thank you for your contributions!

## 8.37.1

- feat(deps): Bump @opentelemetry/instrumentation from 0.53.0 to 0.54.0 for @sentry/opentelemetry ([#14187](https://github.com/getsentry/sentry-javascript/pull/14187))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as Sentry from '@sentry/browser';

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

window.Sentry = {
...Sentry,
// Ensure this is _not_ set
moduleMetadataIntegration: undefined,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
window._testLazyLoadIntegration = async function run() {
const integration = await window.Sentry.lazyLoadIntegration('moduleMetadataIntegration');

window.Sentry.getClient()?.addIntegration(integration());

window._integrationLoaded = true;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { expect } from '@playwright/test';
import { SDK_VERSION } from '@sentry/browser';

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

sentryTest('it allows to lazy load the moduleMetadata integration', async ({ getLocalTestUrl, page }) => {
const url = await getLocalTestUrl({ testDir: __dirname });

await page.route(`https://browser.sentry-cdn.com/${SDK_VERSION}/modulemetadata.min.js`, route => {
return route.fulfill({
status: 200,
contentType: 'application/javascript;',
body: "window.Sentry.moduleMetadataIntegration = () => ({ name: 'ModuleMetadata' })",
});
});

await page.goto(url);

const hasIntegration = await page.evaluate('!!window.Sentry.getClient()?.getIntegrationByName("ModuleMetadata")');
expect(hasIntegration).toBe(false);

const scriptTagsBefore = await page.evaluate<number>('document.querySelectorAll("script").length');

await page.evaluate('window._testLazyLoadIntegration()');
await page.waitForFunction('window._integrationLoaded');

const scriptTagsAfter = await page.evaluate<number>('document.querySelectorAll("script").length');

const hasIntegration2 = await page.evaluate('!!window.Sentry.getClient()?.getIntegrationByName("ModuleMetadata")');
expect(hasIntegration2).toBe(true);

expect(scriptTagsAfter).toBe(scriptTagsBefore + 1);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
integrations: [
Sentry.browserTracingIntegration({
idleTimeout: 9000,
enableLongTask: false,
enableLongAnimationFrame: true,
instrumentPageLoad: false,
enableInp: false,
}),
],
tracesSampleRate: 1,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
function getElapsed(startTime) {
const time = Date.now();
return time - startTime;
}

function handleClick() {
const startTime = Date.now();
while (getElapsed(startTime) < 105) {
//
}
window.history.pushState({}, '', `#myHeading`);
}

const button = document.getElementById('clickme');

console.log('button', button);

button.addEventListener('click', handleClick);
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<button id="clickme">
click me to start the long animation!
</button>

<h1 id="myHeading">My Heading</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';

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

sentryTest(
"doesn't capture long animation frame that starts before a navigation.",
async ({ browserName, getLocalTestPath, page }) => {
// Long animation frames only work on chrome
if (shouldSkipTracingTest() || browserName !== 'chromium') {
sentryTest.skip();
}

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

await page.goto(url);

const navigationTransactionEventPromise = getFirstSentryEnvelopeRequest<Event>(page);

await page.locator('#clickme').click();

const navigationTransactionEvent = await navigationTransactionEventPromise;

expect(navigationTransactionEvent.contexts?.trace?.op).toBe('navigation');

const loafSpans = navigationTransactionEvent.spans?.filter(s => s.op?.startsWith('ui.long-animation-frame'));

expect(loafSpans?.length).toEqual(0);
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ Sentry.init({
}),
],
tracesSampleRate: 1,
debug: true,
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ longTaskButton?.addEventListener('click', () => {
}

// trigger a navigation in the same event loop tick
window.history.pushState({}, '', '/#myHeading');
window.history.pushState({}, '', '#myHeading');
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ sentryTest(

await page.goto(url);

const navigationTransactionEventPromise = getFirstSentryEnvelopeRequest<Event>(page);

await page.locator('#myButton').click();

const navigationTransactionEvent = await getFirstSentryEnvelopeRequest<Event>(page, url);
const navigationTransactionEvent = await navigationTransactionEventPromise;

expect(navigationTransactionEvent.contexts?.trace?.op).toBe('navigation');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const IMPORTED_INTEGRATION_CDN_BUNDLE_PATHS: Record<string, string> = {
reportingObserverIntegration: 'reportingobserver',
sessionTimingIntegration: 'sessiontiming',
feedbackIntegration: 'feedback',
moduleMetadataIntegration: 'modulemetadata',
};

const BUNDLE_PATHS: Record<string, Record<string, string>> = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ test('should capture error with trpc context', async ({ page }) => {
const trpcError = await errorEventPromise;

expect(trpcError).toBeDefined();
expect(trpcError.contexts.trpc).toBeDefined();
expect(trpcError.contexts.trpc.procedure_type).toEqual('mutation');
expect(trpcError.contexts.trpc.input).toEqual({ name: 'I love dogs' });
expect(trpcError.contexts?.trpc).toBeDefined();
expect(trpcError.contexts?.trpc?.procedure_type).toEqual('mutation');
expect(trpcError.contexts?.trpc?.procedure_path).toBe('post.throwError');
expect(trpcError.contexts?.trpc?.input).toEqual({ name: 'I love dogs' });
});

test('should create transaction with trpc input for error', async ({ page }) => {
Expand All @@ -26,9 +27,5 @@ test('should create transaction with trpc input for error', async ({ page }) =>
await page.click('#error-button');

const trpcTransaction = await trpcTransactionPromise;

expect(trpcTransaction).toBeDefined();
expect(trpcTransaction.contexts.trpc).toBeDefined();
expect(trpcTransaction.contexts.trpc.procedure_type).toEqual('mutation');
expect(trpcTransaction.contexts.trpc.input).toEqual({ name: 'I love dogs' });
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,4 @@ test('should create transaction with trpc input for mutation', async ({ page })
const trpcTransaction = await trpcTransactionPromise;

expect(trpcTransaction).toBeDefined();
expect(trpcTransaction.contexts.trpc).toBeDefined();
expect(trpcTransaction.contexts.trpc.procedure_type).toEqual('mutation');
expect(trpcTransaction.contexts.trpc.input).toEqual({ name: 'I love dogs' });
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ test('Should record span for trpc query', async ({ baseURL }) => {
description: `trpc/getSomething`,
}),
);

expect(transaction.contexts?.trpc).toMatchObject({
procedure_type: 'query',
input: 'foobar',
});
});

test('Should record transaction for trpc mutation', async ({ baseURL }) => {
Expand Down Expand Up @@ -70,10 +65,6 @@ test('Should record transaction for trpc mutation', async ({ baseURL }) => {
description: `trpc/createSomething`,
}),
);

expect(transaction.contexts?.trpc).toMatchObject({
procedure_type: 'mutation',
});
});

test('Should record transaction and error for a crashing trpc handler', async ({ baseURL }) => {
Expand All @@ -100,6 +91,9 @@ test('Should record transaction and error for a crashing trpc handler', async ({

await expect(transactionEventPromise).resolves.toBeDefined();
await expect(errorEventPromise).resolves.toBeDefined();

expect((await errorEventPromise).contexts?.trpc?.['procedure_type']).toBe('mutation');
expect((await errorEventPromise).contexts?.trpc?.['procedure_path']).toBe('crashSomething');
});

test('Should record transaction and error for a trpc handler that returns a status code', async ({ baseURL }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,12 @@ test('Waits for sse streaming when sse has been explicitly aborted', async ({ pa
expect(resolveBodyDuration).toBe(0);

// validate abort error was thrown by inspecting console
const consoleBreadcrumb = rootSpan.breadcrumbs?.find(breadcrumb => breadcrumb.category === 'console');
expect(consoleBreadcrumb?.message).toBe('Could not fetch sse AbortError: BodyStreamBuffer was aborted');
expect(rootSpan.breadcrumbs).toContainEqual(
expect.objectContaining({
category: 'console',
message: 'Could not fetch sse AbortError: BodyStreamBuffer was aborted',
}),
);
});

test('Aborts when stream takes longer than 5s, by not updating the span duration', async ({ page }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"@types/react-dom": "18.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-router-dom": "^6.4.1",
"react-router-dom": "6.4.1",
"react-scripts": "5.0.1",
"typescript": "4.9.5"
},
Expand Down
2 changes: 2 additions & 0 deletions dev-packages/node-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"graphql": "^16.3.0",
"http-terminator": "^3.2.0",
"ioredis": "^5.4.1",
"knex": "^2.5.1",
"kafkajs": "2.2.4",
"lru-memoizer": "2.3.0",
"mongodb": "^3.7.3",
Expand All @@ -65,6 +66,7 @@
"redis-4": "npm:redis@^4.6.14",
"reflect-metadata": "0.2.1",
"rxjs": "^7.8.1",
"tedious": "^18.6.1",
"yargs": "^16.2.0"
},
"devDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions dev-packages/node-integration-tests/suites/anr/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ const assert = require('assert');

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

global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };

setTimeout(() => {
process.exit();
}, 10000);
Expand Down
2 changes: 2 additions & 0 deletions dev-packages/node-integration-tests/suites/anr/basic.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import * as crypto from 'crypto';

import * as Sentry from '@sentry/node';

global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' };

setTimeout(() => {
process.exit();
}, 10000);
Expand Down
21 changes: 19 additions & 2 deletions dev-packages/node-integration-tests/suites/anr/test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Event } from '@sentry/types';
import { conditionalTest } from '../../utils';
import { cleanupChildProcesses, createRunner } from '../../utils/runner';

Expand Down Expand Up @@ -64,17 +65,33 @@ const ANR_EVENT_WITH_SCOPE = {
]),
};

const ANR_EVENT_WITH_DEBUG_META: Event = {
...ANR_EVENT_WITH_SCOPE,
debug_meta: {
images: [
{
type: 'sourcemap',
debug_id: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa',
code_file: expect.stringContaining('basic.'),
},
],
},
};

conditionalTest({ min: 16 })('should report ANR when event loop blocked', () => {
afterAll(() => {
cleanupChildProcesses();
});

test('CJS', done => {
createRunner(__dirname, 'basic.js').withMockSentryServer().expect({ event: ANR_EVENT_WITH_SCOPE }).start(done);
createRunner(__dirname, 'basic.js').withMockSentryServer().expect({ event: ANR_EVENT_WITH_DEBUG_META }).start(done);
});

test('ESM', done => {
createRunner(__dirname, 'basic.mjs').withMockSentryServer().expect({ event: ANR_EVENT_WITH_SCOPE }).start(done);
createRunner(__dirname, 'basic.mjs')
.withMockSentryServer()
.expect({ event: ANR_EVENT_WITH_DEBUG_META })
.start(done);
});

test('blocked indefinitely', done => {
Expand Down
Loading

0 comments on commit 9a98d98

Please sign in to comment.