Skip to content

Commit

Permalink
feat: Improve plugin load error handling (#1214)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mattrunyon authored Apr 14, 2023
1 parent 7682984 commit 8ac7dc8
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 20 deletions.
18 changes: 14 additions & 4 deletions packages/code-studio/src/main/AppInit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
Workspace,
WorkspaceStorage,
ServerConfigValues,
DeephavenPluginModule,
} from '@deephaven/redux';
import { setLayoutStorage as setLayoutStorageAction } from '../redux/actions';
import App from './App';
Expand Down Expand Up @@ -75,21 +76,30 @@ async function loadPlugins(): Promise<DeephavenPluginModuleMap> {
`${import.meta.env.VITE_MODULE_PLUGINS_URL}/manifest.json`
);

if (!Array.isArray(manifest.plugins)) {
throw new Error('Plugin manifest JSON does not contain plugins array');
}

log.debug('Plugin manifest loaded:', manifest);
const pluginPromises = [];
const pluginPromises: Promise<unknown>[] = [];
for (let i = 0; i < manifest.plugins.length; i += 1) {
const { name, main } = manifest.plugins[i];
const pluginMainUrl = `${
import.meta.env.VITE_MODULE_PLUGINS_URL
}/${name}/${main}`;
pluginPromises.push(PluginUtils.loadModulePlugin(pluginMainUrl));
}
const pluginModules = await Promise.all(pluginPromises);
const pluginModules = await Promise.allSettled(pluginPromises);

const pluginMap = new Map();
const pluginMap: DeephavenPluginModuleMap = new Map();
for (let i = 0; i < pluginModules.length; i += 1) {
const module = pluginModules[i];
const { name } = manifest.plugins[i];
pluginMap.set(name, pluginModules[i]);
if (module.status === 'fulfilled') {
pluginMap.set(name, module.value as DeephavenPluginModule);
} else {
log.error(`Unable to load plugin ${name}`, module.reason);
}
}
log.info('Plugins loaded:', pluginMap);

Expand Down
25 changes: 9 additions & 16 deletions packages/code-studio/src/plugins/PluginUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,15 @@ class PluginUtils {
static async loadJson(
jsonUrl: string
): Promise<{ plugins: { name: string; main: string }[] }> {
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest();
request.addEventListener('load', () => {
try {
const json = JSON.parse(request.responseText);
resolve(json);
} catch (err) {
reject(err);
}
});
request.addEventListener('error', err => {
reject(err);
});
request.open('GET', jsonUrl);
request.send();
});
const res = await fetch(jsonUrl);
if (!res.ok) {
throw new Error(res.statusText);
}
try {
return await res.json();
} catch {
throw new Error('Could not be parsed as JSON');
}
}
}

Expand Down

0 comments on commit 8ac7dc8

Please sign in to comment.