Skip to content

Commit

Permalink
fix(zone.js): swallow the error when the element callback is not patc…
Browse files Browse the repository at this point in the history
…hable (angular#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 angular#42546

PR Close angular#45400
  • Loading branch information
arturovt authored and PiyushAgrawal1243 committed Mar 30, 2022
1 parent 614edfc commit 06d5b3c
Showing 1 changed file with 20 additions and 7 deletions.
27 changes: 20 additions & 7 deletions packages/zone.js/lib/browser/browser-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,29 @@ export function patchCallbacks(
callbacks.forEach(function(callback) {
const source = `${targetName}.${method}::` + callback;
const prototype = opts.prototype;
if (prototype.hasOwnProperty(callback)) {
const descriptor = api.ObjectGetOwnPropertyDescriptor(prototype, callback);
if (descriptor && descriptor.value) {
descriptor.value = api.wrapWithCurrentZone(descriptor.value, source);
api._redefineProperty(opts.prototype, callback, descriptor);
// Note: 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`.
try {
if (prototype.hasOwnProperty(callback)) {
const descriptor = api.ObjectGetOwnPropertyDescriptor(prototype, callback);
if (descriptor && descriptor.value) {
descriptor.value = api.wrapWithCurrentZone(descriptor.value, source);
api._redefineProperty(opts.prototype, callback, descriptor);
} else if (prototype[callback]) {
prototype[callback] = api.wrapWithCurrentZone(prototype[callback], source);
}
} else if (prototype[callback]) {
prototype[callback] = api.wrapWithCurrentZone(prototype[callback], source);
}
} else if (prototype[callback]) {
prototype[callback] = api.wrapWithCurrentZone(prototype[callback], source);
} catch {
// Note: we leave the catch block empty since there's no way to handle the error related
// to non-writable property.
}
});
}
Expand Down

0 comments on commit 06d5b3c

Please sign in to comment.