test(zone.js): should invoke XHR task even onload handler throw error. (#41562)
Close #41520. This case related to the issue #41522. ``` Zone.root .fork({ name: 'xhr', onHasTask(delegate, currentZone, zone, taskState) { console.log('hasMacrotask', taskState.macroTask); return delegate.hasTask(zone, taskState); }, }) .run(() => { const xhr = new XMLHttpRequest(); xhr.open('GET', 'https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.11.4/zone.min.js'); xhr.addEventListener('load', () => { throw new Error(); }); xhr.send(); }); ``` zone.js invoke all `onload` event handlers before change the XHR task's state from `scheduled` to `notscheduled`, so if any `onload` listener throw error, the XHR task wlll be hang to `scheduled`, and leave the macroTask status in the zone wrongly. This has been fixed in the previous commit, this commit add test to verify the case. PR Close #41562
This commit is contained in:
parent
5c48cd30b5
commit
6910118b0d
|
@ -103,6 +103,77 @@ describe('XMLHttpRequest', function() {
|
|||
req!.send();
|
||||
});
|
||||
|
||||
it('should run onload listeners before internal readystatechange', function(done) {
|
||||
const logs: string[] = [];
|
||||
const xhrZone = Zone.current.fork({
|
||||
name: 'xhr',
|
||||
onInvokeTask: (delegate, curr, target, task, applyThis, applyArgs) => {
|
||||
logs.push('invokeTask ' + task.source);
|
||||
return delegate.invokeTask(target, task, applyThis, applyArgs);
|
||||
}
|
||||
});
|
||||
|
||||
xhrZone.run(function() {
|
||||
const req = new XMLHttpRequest();
|
||||
req.onload = function() {
|
||||
logs.push('onload');
|
||||
(window as any)[Zone.__symbol__('setTimeout')](() => {
|
||||
expect(logs).toEqual([
|
||||
'invokeTask XMLHttpRequest.addEventListener:load', 'onload',
|
||||
'invokeTask XMLHttpRequest.send'
|
||||
])
|
||||
done();
|
||||
});
|
||||
};
|
||||
req.open('get', '/', true);
|
||||
req.send();
|
||||
});
|
||||
});
|
||||
|
||||
it('should invoke xhr task even onload listener throw error', function(done) {
|
||||
const logs: string[] = [];
|
||||
const xhrZone = Zone.current.fork({
|
||||
name: 'xhr',
|
||||
onInvokeTask: (delegate, curr, target, task, applyThis, applyArgs) => {
|
||||
logs.push('invokeTask ' + task.source);
|
||||
return delegate.invokeTask(target, task, applyThis, applyArgs);
|
||||
},
|
||||
onHasTask: (delegate, curr, target, hasTaskState) => {
|
||||
if (hasTaskState.change === 'macroTask') {
|
||||
logs.push('hasTask ' + hasTaskState.macroTask);
|
||||
}
|
||||
return delegate.hasTask(target, hasTaskState);
|
||||
}
|
||||
});
|
||||
|
||||
xhrZone.run(function() {
|
||||
const req = new XMLHttpRequest();
|
||||
req.onload = function() {
|
||||
logs.push('onload');
|
||||
throw new Error('test');
|
||||
};
|
||||
const unhandledRejection = (e: PromiseRejectionEvent) => {
|
||||
logs.push(e.reason.message);
|
||||
};
|
||||
window.addEventListener('unhandledrejection', unhandledRejection);
|
||||
req.addEventListener('load', () => {
|
||||
logs.push('onload1');
|
||||
(window as any)[Zone.__symbol__('setTimeout')](() => {
|
||||
expect(logs).toEqual([
|
||||
'hasTask true', 'invokeTask XMLHttpRequest.addEventListener:load', 'onload',
|
||||
'invokeTask XMLHttpRequest.addEventListener:load', 'onload1',
|
||||
'invokeTask XMLHttpRequest.send', 'hasTask false',
|
||||
'invokeTask Window.addEventListener:unhandledrejection', 'test'
|
||||
]);
|
||||
window.removeEventListener('unhandledrejection', unhandledRejection);
|
||||
done();
|
||||
});
|
||||
});
|
||||
req.open('get', '/', true);
|
||||
req.send();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return null when access ontimeout first time without error', function() {
|
||||
let req: XMLHttpRequest = new XMLHttpRequest();
|
||||
expect(req.ontimeout).toBe(null);
|
||||
|
|
Loading…
Reference in New Issue