Skip to content

Commit

Permalink
feat: when a widget fails, show a fallback error widget
Browse files Browse the repository at this point in the history
  • Loading branch information
maartenbreddels committed Aug 5, 2020
1 parent bfa0e8b commit 85fd9d9
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
32 changes: 32 additions & 0 deletions js/src/errorwidget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as widgets from "@jupyter-widgets/base";

// create a Widget Model that captures an error object
export
function createErrorWidget(error) {
class ErrorWidget extends widgets.DOMWidgetModel {
constructor(attributes, options) {
attributes = {...attributes,
_view_name: 'ErrorWidgetView',
_view_module: 'voila-errorwidget',
_model_module_version: '1.0.0',
_view_module_version: '1.0.0',
failed_module: attributes._view_module,
failed_model_name: attributes._model_name,
error: error}
super(attributes, options);
console.log(attributes);
}
}
return ErrorWidget;
}

export
class ErrorWidgetView extends widgets.DOMWidgetView {
render() {
console.log('render');
const module = this.model.get('failed_module');
const name = this.model.get('failed_model_name');
const error = String(this.model.get('error').stack);
this.el.innerHTML = `Failed to load widget '${name}' from module '${module}', error:<pre>${error}</pre>`;
}
}
21 changes: 19 additions & 2 deletions js/src/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { MessageLoop } from '@phosphor/messaging';

import { requireLoader } from './loader';
import { batchRateMap } from './utils';
import * as errorwidget from './errorwidget';

if (typeof window !== "undefined" && typeof window.define !== "undefined") {
window.define("@jupyter-widgets/base", base);
Expand All @@ -49,6 +50,8 @@ if (typeof window !== "undefined" && typeof window.define !== "undefined") {
window.define("@phosphor/algorithm", PhosphorAlgorithm);
window.define("@phosphor/commands", PhosphorCommands);
window.define("@phosphor/domutils", PhosphorDomutils);

window.define("voila-errorwidget", errorwidget);
}

const WIDGET_MIMETYPE = 'application/vnd.jupyter.widget-view+json';
Expand Down Expand Up @@ -106,10 +109,19 @@ export class WidgetManager extends JupyterLabManager {
}

async loadClass(className, moduleName, moduleVersion) {
try {
return await this._loadClass(className, moduleName, moduleVersion)
} catch(error) {
return errorwidget.createErrorWidget(error);
};
}

async _loadClass(className, moduleName, moduleVersion) {
if (
moduleName === '@jupyter-widgets/base' ||
moduleName === '@jupyter-widgets/controls' ||
moduleName === '@jupyter-widgets/output'
moduleName === '@jupyter-widgets/output' ||
moduleName === 'voila-errorwidget'
) {
return super.loadClass(className, moduleName, moduleVersion);
}
Expand All @@ -120,7 +132,7 @@ export class WidgetManager extends JupyterLabManager {
return module[className];
}
else {
return Promise.reject("Class " + className + " not found in module " + moduleName + "@" + moduleVersion);
throw Error("Class " + className + " not found in module " + moduleName + "@" + moduleVersion);
}
})
}
Expand All @@ -145,6 +157,11 @@ export class WidgetManager extends JupyterLabManager {
version: output.OUTPUT_WIDGET_VERSION,
exports: output
});
this.register({
name: 'voila-errorwidget',
version: '1.0.0',
exports: errorwidget
});
}

async _build_models() {
Expand Down

0 comments on commit 85fd9d9

Please sign in to comment.