Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

When Next.js serves a page from its cache, for example an ISR page or a `cacheComponents` shell, the pageload now has the `page.server_rendering.type` attribute. It is `static` if the whole page came from the cache, and `partially_static` if parts of it rendered for this request. Then the pageload stays connected to this request, as before. If the request that rendered the cached page was sampled, the pageload also links to it. So in Sentry, a cached page no longer looks like missing server instrumentation.

### Other Changes

- fix(core): Read `__sentry_original__` as an own property in `getOriginalFunction` ([#25964](https://github.com/getsentry/sentry-javascript/pull/25964))

Work in this release was contributed by @lazerg and @chiliec. Thank you for your contributions!

## 11.10.0
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/utils/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export function wrapMethod<O extends {}, T extends string & keyof O>(
*/
// eslint-disable-next-line @typescript-eslint/ban-types
export function getOriginalFunction<T extends Function>(func: WrappedFunction<T>): T | undefined {
return func.__sentry_original__;
return Object.prototype.hasOwnProperty.call(func, '__sentry_original__') ? func.__sentry_original__ : undefined;
}

/**
Expand Down
12 changes: 12 additions & 0 deletions packages/core/test/lib/integrations/functiontostring.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@ describe('FunctionToString', () => {
expect(Reflect.apply(Function.prototype.toString, inspectedFunction, new Array(100_000))).toBe(expected);
});

it('does not overflow the stack when the prototype chain loops through a Proxy', () => {
function inspectedFunction(): void {}
Object.setPrototypeOf(inspectedFunction, Object.create(new Proxy(inspectedFunction, {})));
const callToString = Function.prototype.call.bind(Function.prototype.toString) as (thisArg: unknown) => string;
const expected = callToString(inspectedFunction);

const fts = functionToStringIntegration();
getClient()?.addIntegration(fts);

expect(callToString(inspectedFunction)).toBe(expected);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Regression test skips patched toString

Low Severity

The new test binds Function.prototype.toString before addIntegration, so callToString keeps the native function when this case runs first or alone. That path never enters getOriginalFunction and can pass without the overflow fix. Flagged from the review rules: a fix PR's regression test needs to fail without the change.

Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 78f76f3. Configure here.


it('falls back to native toString and does not throw when the carrier read throws', () => {
const foo = {
bar(wat: boolean): boolean {
Expand Down