From 537af3e069fad90a9a38baeff8b1294822b6afda Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Mon, 22 Jun 2026 09:13:41 +0200 Subject: [PATCH] fix(core): avoid uncaught promise errors in injectAsync prefetching Fixes a minor issue where the `preload` function in `injectAsync` might cause an uncaught promise error. I also fixed that in `onIdle` we were passing the wrong function into `assertInInjectionContext`. --- packages/core/src/di/inject_async.ts | 7 ++-- .../test/di/inject_async/inject_async_spec.ts | 35 +++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/core/src/di/inject_async.ts b/packages/core/src/di/inject_async.ts index f7a6788e0de0..dabca71a5159 100644 --- a/packages/core/src/di/inject_async.ts +++ b/packages/core/src/di/inject_async.ts @@ -74,7 +74,10 @@ export function injectAsync( }; if (options?.prefetch) { - options.prefetch().then(() => load()); + options + .prefetch() + .then(() => load()) + .catch(() => {}); } // We can't use `inject` later on because of the async nature of the loader @@ -131,7 +134,7 @@ export type PrefetchTrigger = () => Promise; */ export function onIdle(options?: {timeout?: number}): Promise { if (ngDevMode) { - assertInInjectionContext(injectAsync); + assertInInjectionContext(onIdle); } const idleService = inject(IDLE_SERVICE); diff --git a/packages/core/test/di/inject_async/inject_async_spec.ts b/packages/core/test/di/inject_async/inject_async_spec.ts index e2becca1c264..9d21a43779e3 100644 --- a/packages/core/test/di/inject_async/inject_async_spec.ts +++ b/packages/core/test/di/inject_async/inject_async_spec.ts @@ -301,4 +301,39 @@ describe('injectAsync', () => { jasmine.clock().uninstall(); }); + + it('should not cause an unhandled promise rejection if prefetch trigger rejects', async () => { + await TestBed.runInInjectionContext(async () => { + const fooPromise = injectAsync(() => Promise.resolve(FooService), { + prefetch: () => Promise.reject(new Error('prefetch error')), + }); + + await Promise.resolve(); + + const foo = await fooPromise(); + expect(foo).toBeInstanceOf(FooService); + }); + }); + + it('should not cause an unhandled promise rejection if loader rejects during prefetch', async () => { + await TestBed.runInInjectionContext(async () => { + const fooPromise = injectAsync(() => Promise.reject(new Error('loader error')), { + prefetch: () => Promise.resolve(), + }); + + await Promise.resolve(); + await Promise.resolve(); + await Promise.resolve(); + + let error!: Error; + try { + await fooPromise(); + } catch (e: any) { + error = e; + } + + expect(error).toBeDefined(); + expect(error.message).toBe('loader error'); + }); + }); });