angular-cli icon indicating copy to clipboard operation
angular-cli copied to clipboard

Unhandled promise rejections aren't properly reported in tests

Open sgravrock opened this issue 5 months ago • 5 comments

Which @angular/* package(s) are the source of the bug?

Don't known / other

Is this a regression?

Yes

Description

In an Angular project that uses zone.js, unhandled promise rejections are not reported. In a zoneless Angular project, they are reported twice.

Steps to reproduce:

  1. Create a new Angular project.
  2. Paste the code below into a spec file.
  3. npm t
it('triggers an unhandled rejection', function(done) {
	Promise.reject(new Error('nope'));

	// Make sure the unhandled rejection event has plenty of time to fire before
	// Jasmine finishes running. This helps distinguish between timing issues
	// (event is firing a bit later than usual) and the event not firing at all.
	setTimeout(done, 1000);
});

Expected result: The spec should fail with a single "Unhandled promise rejection: Error: nope" error.

Observed:

  • If the project was set up zoneless, the spec fails with two copies of the expected error.
  • Otherwise, the spec passes.

Please provide a link to a minimal reproduction of the bug

https://github.com/sgravrock/ng-unhandled-rejection

Please provide the exception or error you saw


Please provide the environment you discovered this bug in (run ng version)

_                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 20.1.5
Node: 20.19.0
Package Manager: npm 10.8.2
OS: darwin arm64

Angular: 20.1.6
... common, compiler, compiler-cli, core, forms
... platform-browser, router

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.2001.5
@angular-devkit/core         20.1.5
@angular-devkit/schematics   20.1.5
@angular/build               20.1.5
@angular/cli                 20.1.5
@schematics/angular          20.1.5
rxjs                         7.8.2
typescript                   5.8.3
zone.js                      0.15.1

Anything else?

No response

sgravrock avatar Aug 09 '25 17:08 sgravrock

The error is thrown asynchronously.

If you want to catch it in a zonefull app, you'll need fakeAsync:

  it('triggers an unhandled rejection', fakeAsync(() =>{
    Promise.reject(new Error('test error'));
  }));

In a zoneless app, you'd have to await that promise :

  it('triggers an unhandled rejection', async () => {
    await Promise.reject(new Error('test error'));
  });

JeanMeche avatar Aug 09 '25 22:08 JeanMeche

@JeanMeche That's not quite the issue being described. I haven't looked at the problem when Zone.js is on the page, but it doesn't surprise me entirely (could be related to the global errors patch that at some point may have been put in place for this but doesn’t work anymore?? #63072 or maybe https://github.com/angular/angular/issues/51357#issuecomment-2555564572).

The issue with the zoneless setup is that jasmine is booted twice, once through jasmine-core and once through karma-jasmine, and this causes two of the global error handlers to be installed.

Image

Image

atscott avatar Aug 09 '25 22:08 atscott

Right. The point of unhandled promise rejection detection is to catch cases where the rejection isn't propagated back to Jasmine due to bugs in the spec or the code under test. The feature was originally contributed to Jasmine by the Angular team, for what it's worth.

sgravrock avatar Aug 10 '25 01:08 sgravrock

I took a deeper look into it.

Up to v16, the test fails with an Unhandled promise rejection. (Everytime it's logged twice probably for the reason you already mentionned @atscott) From v17 onwards, the test passes.

Edit: Since zone.js release aren't tied to Angular version, the breakage was introduced in the transition between 0.14.1 and 0.14.2. The single change between those versions is 6d7eb3548c5fc3aedb4a52ff2010141343748e90

JeanMeche avatar Aug 10 '25 23:08 JeanMeche

Great, thanks for confirming without a doubt that it’s https://github.com/angular/angular/issues/51357#issuecomment-2555564572

I think then that the ZoneJs portion of this bug already has a tracking issue (and finally I know why I occasionally come across errors that aren’t failing tests). The other portion is maybe a cli issue so I’ll transfer this to the cli repo.

atscott avatar Aug 11 '25 02:08 atscott