Skip to content

Commit 8ac7dc8

Browse files
authored
feat: Improve plugin load error handling (#1214)
Loads plugins individually instead of failing to register if any plugin fails to load. Previously if any plugin failed to load for any reason then no plugins were registered. Does some validation on if the manifest file exists and the structure of it so that the errors are more descriptive. Does not throw a 2nd error about `Unexpected token <` if there is no manifest file
1 parent 7682984 commit 8ac7dc8

2 files changed

Lines changed: 23 additions & 20 deletions

File tree

packages/code-studio/src/main/AppInit.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
Workspace,
4343
WorkspaceStorage,
4444
ServerConfigValues,
45+
DeephavenPluginModule,
4546
} from '@deephaven/redux';
4647
import { setLayoutStorage as setLayoutStorageAction } from '../redux/actions';
4748
import App from './App';
@@ -75,21 +76,30 @@ async function loadPlugins(): Promise<DeephavenPluginModuleMap> {
7576
`${import.meta.env.VITE_MODULE_PLUGINS_URL}/manifest.json`
7677
);
7778

79+
if (!Array.isArray(manifest.plugins)) {
80+
throw new Error('Plugin manifest JSON does not contain plugins array');
81+
}
82+
7883
log.debug('Plugin manifest loaded:', manifest);
79-
const pluginPromises = [];
84+
const pluginPromises: Promise<unknown>[] = [];
8085
for (let i = 0; i < manifest.plugins.length; i += 1) {
8186
const { name, main } = manifest.plugins[i];
8287
const pluginMainUrl = `${
8388
import.meta.env.VITE_MODULE_PLUGINS_URL
8489
}/${name}/${main}`;
8590
pluginPromises.push(PluginUtils.loadModulePlugin(pluginMainUrl));
8691
}
87-
const pluginModules = await Promise.all(pluginPromises);
92+
const pluginModules = await Promise.allSettled(pluginPromises);
8893

89-
const pluginMap = new Map();
94+
const pluginMap: DeephavenPluginModuleMap = new Map();
9095
for (let i = 0; i < pluginModules.length; i += 1) {
96+
const module = pluginModules[i];
9197
const { name } = manifest.plugins[i];
92-
pluginMap.set(name, pluginModules[i]);
98+
if (module.status === 'fulfilled') {
99+
pluginMap.set(name, module.value as DeephavenPluginModule);
100+
} else {
101+
log.error(`Unable to load plugin ${name}`, module.reason);
102+
}
93103
}
94104
log.info('Plugins loaded:', pluginMap);
95105

packages/code-studio/src/plugins/PluginUtils.tsx

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,15 @@ class PluginUtils {
5858
static async loadJson(
5959
jsonUrl: string
6060
): Promise<{ plugins: { name: string; main: string }[] }> {
61-
return new Promise((resolve, reject) => {
62-
const request = new XMLHttpRequest();
63-
request.addEventListener('load', () => {
64-
try {
65-
const json = JSON.parse(request.responseText);
66-
resolve(json);
67-
} catch (err) {
68-
reject(err);
69-
}
70-
});
71-
request.addEventListener('error', err => {
72-
reject(err);
73-
});
74-
request.open('GET', jsonUrl);
75-
request.send();
76-
});
61+
const res = await fetch(jsonUrl);
62+
if (!res.ok) {
63+
throw new Error(res.statusText);
64+
}
65+
try {
66+
return await res.json();
67+
} catch {
68+
throw new Error('Could not be parsed as JSON');
69+
}
7770
}
7871
}
7972

0 commit comments

Comments
 (0)