Skip to content

Commit

Permalink
fix(zone.js): defineProperty patch should not swallow error (#37582)
Browse files Browse the repository at this point in the history
Close #37432

zone.js monkey patches the `Object.defineProperty` API long time ago
angular/zone.js@383b479
to resolve issues in very old version of Chrome web which override the
property of `CustomElements`, and this is not an issue any longer, so
we want to remove this monkey patch, since it may swallow the errors when the user
want to define property on unconfigurable or frozen object properties.
But currently there are several apps and tests depends on this patch, since
it also change the `configurable` property to `true` by default, so
in this PR we update the logic to not to swallow error any longer unless the property
is the callbacks of `document.registerElements`.

BREAKING CHANGE:

ZoneJS no longer swallows errors produced by `Object.defineProperty` calls.

Prior to this change, ZoneJS monkey patched `Object.defineProperty` and if there is an error
(such as the property is not configurable or not writable) the patched logic swallowed it
and only console.log was produced. This behavior used to hide real errors,
so the logic is now updated to trigger original errors (if any). One exception
where the patch remains in place is `document.registerElement`
(to allow smooth transition for code/polyfills that rely on old behavior in legacy browsers).
If your code relies on the old behavior (where errors were not thrown before),
you may need to update the logic to handle the errors that are no longer masked by ZoneJS patch.

PR Close #37582
  • Loading branch information
JiaLiPassion authored and atscott committed Sep 8, 2020
1 parent 6874772 commit 45a73dd
Showing 1 changed file with 14 additions and 0 deletions.
14 changes: 14 additions & 0 deletions packages/zone.js/lib/browser/define-property.ts
Expand Up @@ -16,6 +16,8 @@ let _defineProperty: any;
let _getOwnPropertyDescriptor: any;
let _create: any;
let unconfigurablesKey: any;
const registerElementsCallbacks =
['createdCallback', 'attachedCallback', 'detachedCallback', 'attributeChangedCallback'];

export function propertyPatch() {
zoneSymbol = Zone.__symbol__;
Expand Down Expand Up @@ -102,6 +104,18 @@ function _tryDefineProperty(obj: any, prop: string, desc: any, originalConfigura
try {
return _defineProperty(obj, prop, desc);
} catch (error) {
let swallowError = false;
if (typeof document !== 'undefined' && obj === document &&
registerElementsCallbacks.find(c => c === prop)) {
// We only swallow the error in registerElement patch
swallowError = true;
}
if (!swallowError) {
throw error;
}
// TODO: @JiaLiPassion, Some application such as `registerElement` patch
// still need to swallow the error, in the future after these applications
// are updated, the following logic can be removed.
let descJson: string|null = null;
try {
descJson = JSON.stringify(desc);
Expand Down

0 comments on commit 45a73dd

Please sign in to comment.