backend-app-api: nicer error messaging when service deps are missing
Co-authored-by: Fredrik Adelöw <freben@gmail.com> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Improved error messaging when failing to instantiate services.
|
||||
@@ -220,4 +220,24 @@ describe('ServiceRegistry', () => {
|
||||
expect(innerFactory).toHaveBeenCalledWith('catalog');
|
||||
expect(innerFactory).toHaveBeenCalledWith('scaffolder');
|
||||
});
|
||||
|
||||
it('should throw if dependencies are not available', async () => {
|
||||
const myFactory = createServiceFactory({
|
||||
service: ref1,
|
||||
deps: { dep: ref2 },
|
||||
async factory({ dep }) {
|
||||
return async pluginId => {
|
||||
const d = await dep(pluginId);
|
||||
return { x: d.x, pluginId };
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
const registry = new ServiceRegistry([myFactory]);
|
||||
const factory = registry.get(ref1)!;
|
||||
|
||||
await expect(factory('catalog')).rejects.toThrow(
|
||||
"Failed to instantiate service '1' for 'catalog'. The following dependent services are missing: '2'",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -56,12 +56,24 @@ export class ServiceRegistry {
|
||||
|
||||
let implementation = this.#implementations.get(factory);
|
||||
if (!implementation) {
|
||||
const factoryDeps = Object.fromEntries(
|
||||
Object.entries(factory.deps).map(([name, serviceRef]) => [
|
||||
name,
|
||||
this.get(serviceRef)!, // TODO: throw
|
||||
]),
|
||||
);
|
||||
const missingRefs = new Array<ServiceRef<unknown>>();
|
||||
const factoryDeps: { [name in string]: FactoryFunc<unknown> } = {};
|
||||
|
||||
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
||||
const target = this.get(serviceRef);
|
||||
if (!target) {
|
||||
missingRefs.push(serviceRef);
|
||||
} else {
|
||||
factoryDeps[name] = target;
|
||||
}
|
||||
}
|
||||
|
||||
if (missingRefs.length) {
|
||||
const missing = missingRefs.map(r => `'${r.id}'`).join(', ');
|
||||
throw new Error(
|
||||
`Failed to instantiate service '${ref.id}' for '${pluginId}'. The following dependent services are missing: ${missing}`,
|
||||
);
|
||||
}
|
||||
|
||||
implementation = {
|
||||
factoryFunc: factory.factory(factoryDeps),
|
||||
|
||||
Reference in New Issue
Block a user