backend-app-api: improved error messaging when default factory loaders throw

Co-authored-by: Fredrik Adelöw <freben@gmail.com>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2022-09-02 11:52:00 +02:00
parent 181c066d2d
commit 06b37e817e
2 changed files with 28 additions and 2 deletions
@@ -276,4 +276,20 @@ describe('ServiceRegistry', () => {
"Failed to instantiate service '1' for 'catalog' because the factory function threw an error, Error: error in plugin catalog",
);
});
it('should decorate error messages thrown by default factory loaders', async () => {
const ref = createServiceRef<string>({
id: '1',
defaultFactory() {
throw new Error('default factory error');
},
});
const registry = new ServiceRegistry([]);
const factory = registry.get(ref)!;
await expect(factory('catalog')).rejects.toThrow(
"Failed to instantiate service '1' because the default factory loader threw an error, Error: default factory error",
);
});
});
@@ -48,11 +48,21 @@ export class ServiceRegistry {
if (!factory) {
let loadedFactory = this.#loadedDefaultFactories.get(defaultFactory!);
if (!loadedFactory) {
loadedFactory = defaultFactory!(ref) as Promise<ServiceFactory>;
loadedFactory = Promise.resolve().then(
() => defaultFactory!(ref) as Promise<ServiceFactory>,
);
this.#loadedDefaultFactories.set(defaultFactory!, loadedFactory);
}
// NOTE: This await is safe as long as #providedFactories is not mutated.
factory = await loadedFactory;
factory = await loadedFactory.catch(error => {
throw new Error(
`Failed to instantiate service '${
ref.id
}' because the default factory loader threw an error, ${stringifyError(
error,
)}`,
);
});
}
let implementation = this.#implementations.get(factory);