Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c67c870
feat(deps): bump @sentry/cli from 2.52.0 to 2.53.0 (#17652)
dependabot[bot] Sep 16, 2025
660d533
ci(test-matrix): Add logs for `getTestMatrix` (#17673)
s1gr1d Sep 17, 2025
4756112
Merge pull request #17682 from getsentry/ab/manual-develop-sync-10.12.0
andreiborza Sep 17, 2025
c0f0375
fix(node): Fix `this` context for vercel AI instrumentation (#17681)
mydea Sep 17, 2025
3410a08
ref(remix): Avoid unnecessary error wrapping `HandleDocumentRequestFu…
mydea Sep 17, 2025
14246fa
chore(nuxt): Bump Vite and Rollup plugins (#17671)
Lms24 Sep 17, 2025
a48cf89
feat(core): Allow to pass `onSuccess` to `handleCallbackErrors` (#17679)
mydea Sep 17, 2025
c022972
ref: Avoid some usage of `SyncPromise` where not needed (#17641)
mydea Sep 17, 2025
2cde2a4
feat(node): Do not drop 300 and 304 status codes by default (#17686)
mydea Sep 17, 2025
5a1faed
ref(core): Add debug log when dropping a span via `ignoreSpans` (#17692)
Lms24 Sep 18, 2025
d039640
fix(core): Ensure builtin stack frames don't affect `thirdPartyErrorF…
Lms24 Sep 18, 2025
3c76c5d
fix(browser): Ensure idle span duration is adjusted when child spans …
Lms24 Sep 19, 2025
97ff2f7
feat(core,node): Add instrumentation for `GoogleGenerativeAI` (#17625)
RulaKhaled Sep 19, 2025
804f7a7
ref(core): Streamline `module_metadata` assignment and cleanup functi…
Lms24 Sep 19, 2025
062d684
ref(core): Avoid looking up anthropic-ai integration options (#17694)
mydea Sep 19, 2025
670c624
fix(core): Fix client hook edge cases around multiple callbacks (#17706)
Lms24 Sep 19, 2025
65fd3b6
ci: Fix lookup of changed E2E test apps (#17707)
mydea Sep 19, 2025
9b22c8a
feat(nextjs): Use `afterProductionCompile` hook for webpack builds (#…
chargome Sep 19, 2025
162143f
fix(nextjs): Enable fetch span when OTel setup is skipped (#17699)
s1gr1d Sep 19, 2025
f3aa997
feat(core): Add logger to core and allow scope to be passed log metho…
AbhiPrasad Sep 19, 2025
c123105
feat(browser): Add option to explicitly end pageload span via `report…
Lms24 Sep 19, 2025
0e0c711
feat(core): Create template attributes in `consoleLoggingIntegration`…
AbhiPrasad Sep 19, 2025
ee4ed05
chore(repo): Add changelog entry for `reportPageLoaded` (#17724)
Lms24 Sep 22, 2025
51c16a4
feat(node): Add extra platforms to `os` context (#17720)
timfish Sep 22, 2025
592ed90
chore: Add link to build and test icon in readme (#17719)
Olexandr88 Sep 22, 2025
9e24a70
chore: Add external contributor to CHANGELOG.md (#17725)
HazAT Sep 22, 2025
cf7913c
feat(nextjs): Promote `useRunAfterProductionCompileHook` to non-exper…
chargome Sep 22, 2025
61b3f97
feat(nextjs): Flip default value for `useRunAfterProductionCompileHoo…
chargome Sep 22, 2025
85e8678
meta(changelog): Update changelog for 10.13.0
chargome Sep 22, 2025
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
76 changes: 76 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,82 @@

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

## 10.13.0

### Important Changes

- **feat(browser): Add option to explicitly end pageload span via `reportPageLoaded()` ([#17697](https://github.com/getsentry/sentry-javascript/pull/17697))**

With this release you can take manual control of ending the pageload span. Usually this span is ended automatically by the SDK, based on a period of inactivity after the initial page was loaded in the browser. If you want full control over the pageload duration, you can tell Sentry, when your page was fully loaded:

```js
Sentry.init({
//...
integrations: [
// 1. Enable manual pageload reporting
Sentry.browserTracingIntegration({ enableReportPageLoaded: true }),
],
});

// 2. Whenever you decide the page is loaded, call:
Sentry.reportPageLoaded();
```

Note that if `Sentry.reportPageLoaded()` is not called within 30 seconds of the initial pageload (or whatever value the `finalTimeout` option is set to), the pageload span will be ended automatically.

- **feat(core,node): Add instrumentation for `GoogleGenerativeAI` ([#17625](https://github.com/getsentry/sentry-javascript/pull/17625))**

The SDK now automatically instruments the `@google/generative-ai` package to provide insights into your AI operations.

- **feat(nextjs): Promote `useRunAfterProductionCompileHook` to non-experimental build option ([#17721](https://github.com/getsentry/sentry-javascript/pull/17721))**

The `useRunAfterProductionCompileHook` option is no longer experimental and is now a stable build option for Next.js projects.

- **feat(nextjs): Use `afterProductionCompile` hook for webpack builds ([#17655](https://github.com/getsentry/sentry-javascript/pull/17655))**

Next.js projects using webpack can opt-in to use the `useRunAfterProductionCompileHook` hook for source map uploads.

- **feat(nextjs): Flip default value for `useRunAfterProductionCompileHook` for Turbopack builds ([#17722](https://github.com/getsentry/sentry-javascript/pull/17722))**

The `useRunAfterProductionCompileHook` option is now enabled by default for Turbopack builds, enabling automated source map uploads.

- **feat(node): Do not drop 300 and 304 status codes by default ([#17686](https://github.com/getsentry/sentry-javascript/pull/17686))**

HTTP transactions with 300 and 304 status codes are now captured by default, providing better visibility into redirect and caching behavior.

### Other Changes

- feat(core): Add logger to core and allow scope to be passed log methods ([#17698](https://github.com/getsentry/sentry-javascript/pull/17698))
- feat(core): Allow to pass `onSuccess` to `handleCallbackErrors` ([#17679](https://github.com/getsentry/sentry-javascript/pull/17679))
- feat(core): Create template attributes in `consoleLoggingIntegration` ([#17703](https://github.com/getsentry/sentry-javascript/pull/17703))
- feat(deps): bump @sentry/cli from 2.52.0 to 2.53.0 ([#17652](https://github.com/getsentry/sentry-javascript/pull/17652))
- feat(node): Add extra platforms to `os` context ([#17720](https://github.com/getsentry/sentry-javascript/pull/17720))
- fix(browser): Ensure idle span duration is adjusted when child spans are ignored ([#17700](https://github.com/getsentry/sentry-javascript/pull/17700))
- fix(core): Ensure builtin stack frames don't affect `thirdPartyErrorFilterIntegration` ([#17693](https://github.com/getsentry/sentry-javascript/pull/17693))
- fix(core): Fix client hook edge cases around multiple callbacks ([#17706](https://github.com/getsentry/sentry-javascript/pull/17706))
- fix(nextjs): Enable fetch span when OTel setup is skipped ([#17699](https://github.com/getsentry/sentry-javascript/pull/17699))
- fix(node): Fix `this` context for vercel AI instrumentation ([#17681](https://github.com/getsentry/sentry-javascript/pull/17681))

<details>
<summary> <strong>Internal Changes</strong> </summary>

- chore: Add external contributor to CHANGELOG.md ([#17725](https://github.com/getsentry/sentry-javascript/pull/17725))
- chore: Add link to build and test icon in readme ([#17719](https://github.com/getsentry/sentry-javascript/pull/17719))
- chore(nuxt): Bump Vite and Rollup plugins ([#17671](https://github.com/getsentry/sentry-javascript/pull/17671))
- chore(repo): Add changelog entry for `reportPageLoaded` ([#17724](https://github.com/getsentry/sentry-javascript/pull/17724))
- ci: Fix lookup of changed E2E test apps ([#17707](https://github.com/getsentry/sentry-javascript/pull/17707))
- ci(test-matrix): Add logs for `getTestMatrix` ([#17673](https://github.com/getsentry/sentry-javascript/pull/17673))
- ref: Avoid some usage of `SyncPromise` where not needed ([#17641](https://github.com/getsentry/sentry-javascript/pull/17641))
- ref(core): Add debug log when dropping a span via `ignoreSpans` ([#17692](https://github.com/getsentry/sentry-javascript/pull/17692))
- ref(core): Avoid looking up anthropic-ai integration options ([#17694](https://github.com/getsentry/sentry-javascript/pull/17694))
- ref(core): Streamline `module_metadata` assignment and cleanup functions ([#17696](https://github.com/getsentry/sentry-javascript/pull/17696))
- ref(remix): Avoid unnecessary error wrapping `HandleDocumentRequestFunction` ([#17680](https://github.com/getsentry/sentry-javascript/pull/17680))
- Revert "[Gitflow] Merge master into develop"

</details>

Work in this release was contributed by @Olexandr88. Thank you for your contribution!

## 10.12.0

### Important Changes
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ _Bad software is everywhere, and we're tired of it. Sentry is on a mission to he
faster, so we can get back to enjoying technology. If you want to join us
[<kbd>**Check out our open positions**</kbd>](https://sentry.io/careers/)_

![Build & Test](https://github.com/getsentry/sentry-javascript/workflows/CI:%20Build%20&%20Test/badge.svg)
[![Build & Test](https://github.com/getsentry/sentry-javascript/workflows/CI:%20Build%20&%20Test/badge.svg)](https://github.com/getsentry/sentry-javascript/actions)
[![codecov](https://codecov.io/gh/getsentry/sentry-javascript/branch/develop/graph/badge.svg)](https://codecov.io/gh/getsentry/sentry-javascript)
[![npm version](https://img.shields.io/npm/v/@sentry/core.svg)](https://www.npmjs.com/package/@sentry/core)
[![Discord](https://img.shields.io/discord/621778831602221064)](https://discord.gg/Ww9hbqr)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as Sentry from '@sentry/browser';
// eslint-disable-next-line import/no-duplicates
import { thirdPartyErrorFilterIntegration } from '@sentry/browser';
// eslint-disable-next-line import/no-duplicates
import { captureConsoleIntegration } from '@sentry/browser';

// This is the code the bundler plugin would inject to mark the init bundle as a first party module:
var _sentryModuleMetadataGlobal =
typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: typeof self !== 'undefined'
? self
: {};

_sentryModuleMetadataGlobal._sentryModuleMetadata = _sentryModuleMetadataGlobal._sentryModuleMetadata || {};

_sentryModuleMetadataGlobal._sentryModuleMetadata[new Error().stack] = Object.assign(
{},
_sentryModuleMetadataGlobal._sentryModuleMetadata[new Error().stack],
{
'_sentryBundlerPluginAppKey:my-app': true,
},
);

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
integrations: [
thirdPartyErrorFilterIntegration({ behaviour: 'apply-tag-if-contains-third-party-frames', filterKeys: ['my-app'] }),
captureConsoleIntegration({ levels: ['error'], handled: false }),
],
attachStacktrace: true,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// This is the code the bundler plugin would inject to mark the subject bundle as a first party module:
var _sentryModuleMetadataGlobal =
typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: typeof self !== 'undefined'
? self
: {};

_sentryModuleMetadataGlobal._sentryModuleMetadata = _sentryModuleMetadataGlobal._sentryModuleMetadata || {};

_sentryModuleMetadataGlobal._sentryModuleMetadata[new Error().stack] = Object.assign(
{},
_sentryModuleMetadataGlobal._sentryModuleMetadata[new Error().stack],
{
'_sentryBundlerPluginAppKey:my-app': true,
},
);

const errorBtn = document.getElementById('errBtn');
errorBtn.addEventListener('click', async () => {
Promise.allSettled([Promise.reject('I am a first party Error')]).then(values =>
values.forEach(value => {
if (value.status === 'rejected') console.error(value.reason);
}),
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<script src="thirdPartyScript.js"></script>
<button id="errBtn">Throw 1st part yerror</button>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { expect } from '@playwright/test';
import { sentryTest } from '../../../utils/fixtures';
import { envelopeRequestParser, waitForErrorRequest } from '../../../utils/helpers';

const bundle = process.env.PW_BUNDLE || '';
// We only want to run this in non-CDN bundle mode because
// thirdPartyErrorFilterIntegration is only available in the NPM package
if (bundle.startsWith('bundle')) {
sentryTest.skip();
}

sentryTest('tags event if contains at least one third-party frame', async ({ getLocalTestUrl, page }) => {
const url = await getLocalTestUrl({ testDir: __dirname });

const errorEventPromise = waitForErrorRequest(page, e => {
return e.exception?.values?.[0]?.value === 'I am a third party Error';
});

await page.route('**/thirdPartyScript.js', route =>
route.fulfill({
status: 200,
body: readFileSync(join(__dirname, 'thirdPartyScript.js')),
}),
);

await page.goto(url);

const errorEvent = envelopeRequestParser(await errorEventPromise);
expect(errorEvent.tags?.third_party_code).toBe(true);
});

/**
* This test seems a bit more complicated than necessary but this is intentional:
* When using `captureConsoleIntegration` in combination with `thirdPartyErrorFilterIntegration`
* and `attachStacktrace: true`, the stack trace includes native code stack frames which previously broke
* the third party error filtering logic.
*
* see https://github.com/getsentry/sentry-javascript/issues/17674
*/
sentryTest(
"doesn't tag event if doesn't contain third-party frames",
async ({ getLocalTestUrl, page, browserName }) => {
const url = await getLocalTestUrl({ testDir: __dirname });

const errorEventPromise = waitForErrorRequest(page, e => {
return e.exception?.values?.[0]?.value === 'I am a first party Error';
});

await page.route('**/thirdPartyScript.js', route =>
route.fulfill({
status: 200,
body: readFileSync(join(__dirname, 'thirdPartyScript.js')),
}),
);

await page.goto(url);

await page.click('#errBtn');

const errorEvent = envelopeRequestParser(await errorEventPromise);

expect(errorEvent.tags?.third_party_code).toBeUndefined();

// ensure the stack trace includes native code stack frames which previously broke
// the third party error filtering logic
if (browserName === 'chromium') {
expect(errorEvent.exception?.values?.[0]?.stacktrace?.frames).toContainEqual({
filename: '<anonymous>',
function: 'Array.forEach',
in_app: true,
});
} else if (browserName === 'webkit') {
expect(errorEvent.exception?.values?.[0]?.stacktrace?.frames).toContainEqual({
filename: '[native code]',
function: 'forEach',
in_app: true,
});
}
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
setTimeout(() => {
throw new Error('I am a third party Error');
}, 100);
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,12 @@ console.log('Mixed:', 'prefix', { obj: true }, [4, 5, 6], 'suffix');

console.log('');

// Test console substitution patterns (should NOT generate template attributes)
console.log('String substitution %s %d', 'test', 42);
console.log('Object substitution %o', { key: 'value' });

// Test multiple arguments without substitutions (should generate template attributes)
console.log('first', 0, 1, 2);
console.log('hello', true, null, undefined);

Sentry.flush();
Loading
Loading