Skip to content

[zonejs] XMLHttpRequest macrotask left hanging if onload throws #41520

@mleibman

Description

@mleibman

🐞 bug report

Affected Package

The issue is caused by package @angular/zone.js.

Is this a regression?

AFAICT it has always been like this.

Description

ZoneJS invokes the XHR macrotask after all existing load handlers run, but if any of them throw an unhandled exception, the task remains stuck in a scheduled state and none of the delegate hooks (e.g. onInvokeTask()) run. This creates problems for test environments and any instrumentation that relies on task counts.

(It is somewhat similar to issue #38795.)

🔬 Minimal Reproduction

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();
  });

This code ends by printing hasMacrotask true and the XHR task left in a scheduled state.

Note that this repro specifically forks the root zone. If you try to repro this in StackBlitz or in Angular's NgZone and for the current zone instead, you'll need to wrap the addEventListener() call in Zone.root.run() to make it work. The reason is that NgZone implements a onHandleError() delegate hook that always returns false, and the exception get swallowed instead of being thrown.

Metadata

Metadata

Assignees

Labels

area: zonesIssues related to zone.js

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions