Skip to content

Commit e0224fd

Browse files
ya-nshmeta-codesync[bot]
authored andcommitted
fix: validate PerformanceObserver observe options
Summary: Harden `PerformanceObserver.observe()` option validation so invalid observer configurations fail deterministically before we register a native observer. This fixes a few user-facing gaps in the current implementation: - calling `observe()` with no options now throws the expected argument error instead of destructuring `undefined` - the `entryTypes` / `type` validation messages now match the actual invalid condition - empty `entryTypes: []` is rejected instead of silently creating an observer that observes nothing - `entryTypes` combined with `buffered` is rejected before native registration, matching the existing `durationThreshold` guard The goal is to prevent malformed performance observer setup from silently succeeding or failing with misleading errors in apps and performance tooling. ## Changelog: [GENERAL] [FIXED] - Validate invalid PerformanceObserver observe option combinations before native registration X-link: #57030 Reviewed By: javache Differential Revision: D107361950 Pulled By: rubennorte fbshipit-source-id: eb0614fc20541f3cc2a7acacbbef63394ffcd0a1
1 parent ca2e11a commit e0224fd

2 files changed

Lines changed: 41 additions & 4 deletions

File tree

‎packages/react-native/src/private/webapis/performance/PerformanceObserver.js‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,18 +201,30 @@ export class PerformanceObserver {
201201
return observerHandle;
202202
}
203203

204-
#validateObserveOptions(options: PerformanceObserverInit): void {
205-
const {type, entryTypes, durationThreshold} = options;
204+
#validateObserveOptions(options: ?PerformanceObserverInit): void {
205+
if (options == null) {
206+
throw new TypeError(
207+
"Failed to execute 'observe' on 'PerformanceObserver': 1 argument required, but only 0 present.",
208+
);
209+
}
210+
211+
const {type, entryTypes, durationThreshold, buffered} = options;
206212

207213
if (!type && !entryTypes) {
208214
throw new TypeError(
209-
"Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and type arguments.",
215+
"Failed to execute 'observe' on 'PerformanceObserver': An observe() call must include either entryTypes or type arguments.",
210216
);
211217
}
212218

213219
if (entryTypes && type) {
214220
throw new TypeError(
215-
"Failed to execute 'observe' on 'PerformanceObserver': An observe() call must include either entryTypes or type arguments.",
221+
"Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and type arguments.",
222+
);
223+
}
224+
225+
if (entryTypes && buffered != null) {
226+
throw new TypeError(
227+
"Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and buffered arguments.",
216228
);
217229
}
218230

‎packages/react-native/src/private/webapis/performance/__tests__/PerformanceObserver-itest.js‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,31 @@ describe('PerformanceObserver', () => {
9696
expect(entries2.getEntries()[1]).toBe(measure);
9797
});
9898

99+
describe('observe()', () => {
100+
it('rejects invalid entry type option combinations before registering with native', () => {
101+
const callback = jest.fn();
102+
const observer = new PerformanceObserver(callback);
103+
104+
// $FlowExpectedError[incompatible-call]
105+
expect(() => observer.observe()).toThrow(
106+
"Failed to execute 'observe' on 'PerformanceObserver': 1 argument required, but only 0 present.",
107+
);
108+
expect(() => observer.observe({})).toThrow(
109+
"Failed to execute 'observe' on 'PerformanceObserver': An observe() call must include either entryTypes or type arguments.",
110+
);
111+
expect(() =>
112+
observer.observe({entryTypes: ['mark'], type: 'measure'}),
113+
).toThrow(
114+
"Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and type arguments.",
115+
);
116+
expect(() =>
117+
observer.observe({entryTypes: ['mark'], buffered: true}),
118+
).toThrow(
119+
"Failed to execute 'observe' on 'PerformanceObserver': An observe() call must not include both entryTypes and buffered arguments.",
120+
);
121+
});
122+
});
123+
99124
describe('takeRecords()', () => {
100125
it('provides all buffered events and clears the buffer', () => {
101126
const callback = jest.fn();

0 commit comments

Comments
 (0)