Skip to content

Commit 4ea70e3

Browse files
arturovtdylhunn
authored andcommitted
fix(zone.js): swallow the error when the element callback is not patchable (#45400)
The `patchCallbacks` is used for patching the `document.registerElement` and `customElements.define`. We explicitly wrap the patching code into try-catch since callbacks may be already patched by other web components frameworks (e.g. LWC), and they make those properties non-writable. This means that patching callback will throw an error `cannot assign to read-only property`. See this code as an example: https://github.com/salesforce/lwc/blob/master/packages/@lwc/engine-core/src/framework/base-bridge-element.ts#L180-L186 We don't want to stop the application rendering if we couldn't patch some callback, e.g. `attributeChangedCallback`. PR Close #42546 PR Close #45400
1 parent 1177b4e commit 4ea70e3

File tree

1 file changed

+20
-7
lines changed

1 file changed

+20
-7
lines changed

packages/zone.js/lib/browser/browser-util.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,29 @@ export function patchCallbacks(
1717
callbacks.forEach(function(callback) {
1818
const source = `${targetName}.${method}::` + callback;
1919
const prototype = opts.prototype;
20-
if (prototype.hasOwnProperty(callback)) {
21-
const descriptor = api.ObjectGetOwnPropertyDescriptor(prototype, callback);
22-
if (descriptor && descriptor.value) {
23-
descriptor.value = api.wrapWithCurrentZone(descriptor.value, source);
24-
api._redefineProperty(opts.prototype, callback, descriptor);
20+
// Note: the `patchCallbacks` is used for patching the `document.registerElement` and
21+
// `customElements.define`. We explicitly wrap the patching code into try-catch since
22+
// callbacks may be already patched by other web components frameworks (e.g. LWC), and they
23+
// make those properties non-writable. This means that patching callback will throw an error
24+
// `cannot assign to read-only property`. See this code as an example:
25+
// https://github.com/salesforce/lwc/blob/master/packages/@lwc/engine-core/src/framework/base-bridge-element.ts#L180-L186
26+
// We don't want to stop the application rendering if we couldn't patch some
27+
// callback, e.g. `attributeChangedCallback`.
28+
try {
29+
if (prototype.hasOwnProperty(callback)) {
30+
const descriptor = api.ObjectGetOwnPropertyDescriptor(prototype, callback);
31+
if (descriptor && descriptor.value) {
32+
descriptor.value = api.wrapWithCurrentZone(descriptor.value, source);
33+
api._redefineProperty(opts.prototype, callback, descriptor);
34+
} else if (prototype[callback]) {
35+
prototype[callback] = api.wrapWithCurrentZone(prototype[callback], source);
36+
}
2537
} else if (prototype[callback]) {
2638
prototype[callback] = api.wrapWithCurrentZone(prototype[callback], source);
2739
}
28-
} else if (prototype[callback]) {
29-
prototype[callback] = api.wrapWithCurrentZone(prototype[callback], source);
40+
} catch {
41+
// Note: we leave the catch block empty since there's no way to handle the error related
42+
// to non-writable property.
3043
}
3144
});
3245
}

0 commit comments

Comments
 (0)