Skip to content

Commit b618b5a

Browse files
arturovtthePunderWoman
authored andcommittedOct 11, 2022
fix(zone.js): cancel tasks only when they are scheduled or running (#46435)
Currently, there's no check if the task (that is being canceled) has the right state. Only `scheduled` and `running` tasks can be canceled. If the task has a non-appropriate state, then an error will be thrown. Cancelation should not throw an error on an already canceled task, e.g. `clearTimeout` does not throw errors when it's called multiple times on the same timer. PR Close #45711 PR Close #46435
1 parent 96b7fe9 commit b618b5a

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed
 

‎packages/zone.js/lib/zone.ts

+5
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,11 @@ const Zone: ZoneType = (function(global: any) {
956956
throw new Error(
957957
'A task can only be cancelled in the zone of creation! (Creation: ' +
958958
(task.zone || NO_ZONE).name + '; Execution: ' + this.name + ')');
959+
960+
if (task.state !== scheduled && task.state !== running) {
961+
return;
962+
}
963+
959964
(task as ZoneTask<any>)._transitionTo(canceling, scheduled, running);
960965
try {
961966
this._zoneDelegate.cancelTask(this, task);

‎packages/zone.js/test/common/task.spec.ts

+22
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,28 @@ describe('task lifecycle', () => {
907907
}));
908908
});
909909

910+
// Test specific to https://github.com/angular/angular/issues/45711
911+
it('should not throw an error when the task has been canceled previously and is attemped to be canceled again',
912+
() => {
913+
testFnWithLoggedTransitionTo(() => {
914+
Zone.current.fork({name: 'testCancelZone'}).run(() => {
915+
const task =
916+
Zone.current.scheduleEventTask('testEventTask', noop, undefined, noop, noop);
917+
Zone.current.cancelTask(task);
918+
Zone.current.cancelTask(task);
919+
});
920+
expect(log.map(item => {
921+
return {toState: item.toState, fromState: item.fromState};
922+
}))
923+
.toEqual([
924+
{toState: 'scheduling', fromState: 'notScheduled'},
925+
{toState: 'scheduled', fromState: 'scheduling'},
926+
{toState: 'canceling', fromState: 'scheduled'},
927+
{toState: 'notScheduled', fromState: 'canceling'}
928+
]);
929+
});
930+
});
931+
910932
describe('reschedule zone', () => {
911933
let callbackLogs: ({pos: string, method: string, zone: string, task: string}|HasTaskState)[];
912934
const newZone = Zone.root.fork({

0 commit comments

Comments
 (0)
Please sign in to comment.