backend-app-api: settle all inits before exiting on error
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -418,6 +418,49 @@ describe('BackendInitializer', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should forward errors when multiple plugins fail to start', async () => {
|
||||
const init = new BackendInitializer([]);
|
||||
init.add(
|
||||
createBackendPlugin({
|
||||
pluginId: 'test-1',
|
||||
register(reg) {
|
||||
reg.registerInit({
|
||||
deps: {},
|
||||
async init() {
|
||||
throw new Error('NOPE A');
|
||||
},
|
||||
});
|
||||
},
|
||||
}),
|
||||
);
|
||||
init.add(
|
||||
createBackendPlugin({
|
||||
pluginId: 'test-2',
|
||||
register(reg) {
|
||||
reg.registerInit({
|
||||
deps: {},
|
||||
async init() {
|
||||
throw new Error('NOPE B');
|
||||
},
|
||||
});
|
||||
},
|
||||
}),
|
||||
);
|
||||
const result = init.start();
|
||||
|
||||
await expect(result).rejects.toThrow('Backend startup failed');
|
||||
await expect(result).rejects.toMatchObject({
|
||||
errors: [
|
||||
expect.objectContaining({
|
||||
message: "Plugin 'test-1' startup failed; caused by Error: NOPE A",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
message: "Plugin 'test-2' startup failed; caused by Error: NOPE B",
|
||||
}),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should forward errors when modules fail to start', async () => {
|
||||
const init = new BackendInitializer([]);
|
||||
init.add(testPlugin);
|
||||
|
||||
@@ -275,7 +275,7 @@ export class BackendInitializer {
|
||||
);
|
||||
|
||||
// All plugins are initialized in parallel
|
||||
await Promise.all(
|
||||
const results = await Promise.allSettled(
|
||||
allPluginIds.map(async pluginId => {
|
||||
// Initialize all eager services
|
||||
await this.#serviceRegistry.initializeEagerServicesWithScope(
|
||||
@@ -345,6 +345,16 @@ export class BackendInitializer {
|
||||
}),
|
||||
);
|
||||
|
||||
const initErrors = results.flatMap(r =>
|
||||
r.status === 'rejected' ? [r.reason] : [],
|
||||
);
|
||||
if (initErrors.length === 1) {
|
||||
throw initErrors[0];
|
||||
} else if (initErrors.length > 1) {
|
||||
// TODO(Rugvip): Seems like there aren't proper types for AggregateError yet
|
||||
throw new (AggregateError as any)(initErrors, 'Backend startup failed');
|
||||
}
|
||||
|
||||
// Once all plugins and modules have been initialized, we can signal that the backend has started up successfully
|
||||
const lifecycleService = await this.#getRootLifecycleImpl();
|
||||
await lifecycleService.startup();
|
||||
|
||||
Reference in New Issue
Block a user