Close#41522
`zone.js` patches event listeners and run all event listeners together, if
one event handler throws error, the listeners afterward may not be invoked.
Reproduction:
```
export class AppComponent implements AfterViewInit {
@ViewChild('btn') btn: ElementRef;
title = 'event-error';
constructor(private ngZone: NgZone) {}
ngAfterViewInit() {
this.ngZone.runOutsideAngular(() => {
this.btn.nativeElement.addEventListener('click', () => {
throw new Error('test1');
});
this.btn.nativeElement.addEventListener('click', () => {
console.log('add eventlistener click');
});
});
}
}
```
Until now no Angular users report this issue becuase in the `ngZone`, all
error will be caught and will not rethrow, so the event listeners afterward
will still continue to execute, but if the event handlers are outside of `ngZone`,
the error will break the execution.
This commit catch all errors, and after all event listeners finished invocation,
rethrow the errors in seperate `microTasks`, the reason I am using `microTask` here
is to handle multiple errors case.
PR Close#41562
Close#41522
`zone.js` patches event listeners and run all event listeners together, if
one event handler throws error, the listeners afterward may not be invoked.
Reproduction:
```
export class AppComponent implements AfterViewInit {
@ViewChild('btn') btn: ElementRef;
title = 'event-error';
constructor(private ngZone: NgZone) {}
ngAfterViewInit() {
this.ngZone.runOutsideAngular(() => {
this.btn.nativeElement.addEventListener('click', () => {
throw new Error('test1');
});
this.btn.nativeElement.addEventListener('click', () => {
console.log('add eventlistener click');
});
});
}
}
```
Until now no Angular users report this issue becuase in the `ngZone`, all
error will be caught and will not rethrow, so the event listeners afterward
will still continue to execute, but if the event handlers are outside of `ngZone`,
the error will break the execution.
This commit catch all errors, and after all event listeners finished invocation,
rethrow the errors in seperate `microTasks`, the reason I am using `microTask` here
is to handle multiple errors case.
PR Close#41562
Close#38863
Monkey patches `queueMicrotask()` API, so the callback runs in the zone
when scheduled, and also the task is run as `microTask`.
```
Zone.current.fork({
name: 'queueMicrotask',
onScheduleTask: (delegate: ZoneDelegate, curr: Zone, target: Zone, task: Task) => {
logs.push(task.type);
logs.push(task.source);
return delegate.scheduleTask(target, task);
}
}).run(() => {
queueMicrotask(() => {
expect(logs).toEqual(['microTask', 'queueMicrotask']);
expect(Zone.current.name).toEqual('queueMicrotask');
done();
});
});
```
PR Close#38904
Close#38795
in the XMLHttpRequest patch, when get `readystatechange` event, zone.js try to
invoke `load` event listener first, then call `invokeTask` to finish the
`XMLHttpRequest::send` macroTask, but if the request failed because the
server can not be reached, the `load` event listener will not be invoked,
so the `invokeTask` of the `XMLHttpRequest::send` will not be triggered either,
so we will have a non finished macroTask there which will make the Zone
not stable, also memory leak.
So in this PR, if the `XMLHttpRequest.status = 0` when we get the `readystatechange`
event, that means something wents wrong before we reached the server, we need to
invoke the task to finish the macroTask.
PR Close#38836
Since the `defineProperty` not swallow error any longer, now the tests compile
source code in `commonjs` mode, and the code generated includes the code like this
```
Object.defineProperty(exports, "__esModule", {value: true});
```
And the `exports` is undefined in some browsers, but the error is swallowed before
this PR, and all tests run successfully, but it is not correct behavior. After this PR,
the code above failed. So we need to compile the source code in `umd` mode.
PR Close#37582
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
Separate `EventTarget`, `FileReader`, `MutationObserver` and `IntersectionObserver` patches into different module.
So the user can disable those modules separately.
PR Close#31657
Monkey patch `MessagePort.prototype.onmessage` and `MessagePort.prototype.onmessageerror` to make
these properties's value(callback function) run in the zone when these value are set.
PR Close#34610