Skip to content

Commit 0c0f8c6

Browse files
authored
fix(core): Do not throw when trying to fill readonly properties (#14402)
This PR adds a guard to avoid us throwing if we try to fill a readonly property on an object. Generally speaking this should not work, but it does not hurt us to be defensive here and try-catch this to avoid breaking users apps. Fixes #14368
1 parent 3fe2eae commit 0c0f8c6

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

packages/core/src/utils-hoist/object.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ export function fill(source: { [key: string]: any }, name: string, replacementFa
3232
markFunctionWrapped(wrapped, original);
3333
}
3434

35-
source[name] = wrapped;
35+
try {
36+
source[name] = wrapped;
37+
} catch {
38+
DEBUG_BUILD && logger.log(`Failed to replace method "${name}" in object`, source);
39+
}
3640
}
3741

3842
/**

packages/core/test/utils-hoist/object.test.ts

+23
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,29 @@ describe('fill()', () => {
3131
expect(replacement).toBeCalled();
3232
});
3333

34+
test('does not throw on readonly properties', () => {
35+
const originalFn = () => 41;
36+
const source = {
37+
get prop() {
38+
return originalFn;
39+
},
40+
set prop(_fn: () => number) {
41+
throw new Error('OH NO, this is not writeable...');
42+
},
43+
};
44+
45+
expect(source.prop()).toEqual(41);
46+
47+
const replacement = jest.fn().mockImplementation(() => {
48+
return () => 42;
49+
});
50+
fill(source, 'prop', replacement);
51+
expect(replacement).toBeCalled();
52+
53+
expect(source.prop).toBe(originalFn);
54+
expect(source.prop()).toEqual(41);
55+
});
56+
3457
test('can do anything inside replacement function', () => {
3558
const source = {
3659
foo: (): number => 42,

0 commit comments

Comments
 (0)