diff --git a/apis/nucleus/src/components/Cell.jsx b/apis/nucleus/src/components/Cell.jsx index 496d41e47..4de3d878f 100644 --- a/apis/nucleus/src/components/Cell.jsx +++ b/apis/nucleus/src/components/Cell.jsx @@ -17,6 +17,7 @@ import InstanceContext from '../contexts/InstanceContext'; import useObjectSelections from '../hooks/useObjectSelections'; import eventmixin from '../selections/event-mixin'; import useStyling from '../hooks/useStyling'; +import RenderError from '../utils/render-error'; /** * @interface @@ -518,7 +519,10 @@ const Cell = forwardRef( if (state.loading && !state.longRunningQuery) { Content = ; } else if (state.error) { - onError && onError(state.error.errorObject); + if (onError) { + const e = state.error.errorObject ? state.error.errorObject : new RenderError(state.error.title); + onError(e); + } Content = ; } else if (state.loaded) { Content = ( diff --git a/apis/nucleus/src/object/create-session-object.js b/apis/nucleus/src/object/create-session-object.js index 5239b258f..74c3d64c8 100644 --- a/apis/nucleus/src/object/create-session-object.js +++ b/apis/nucleus/src/object/create-session-object.js @@ -11,7 +11,7 @@ import init from './initiate'; * @property {HTMLElement} element Target html element to render in to * @property {object=} options Options passed into the visualisation * @property {function=} onRender Callback function called after rendering successfully - * @property {function=} onError Callback function called if an error occurs + * @property {function(RenderError)=} onError Callback function called if an error occurs * @property {Plugin[]} [plugins] plugins passed into the visualisation * @property {string=} id For existing objects: Engine identifier of object to render * @property {string=} type For creating objects: Type of visualisation to render diff --git a/apis/nucleus/src/sn/load.js b/apis/nucleus/src/sn/load.js index d540993b7..a61279dfe 100644 --- a/apis/nucleus/src/sn/load.js +++ b/apis/nucleus/src/sn/load.js @@ -1,4 +1,4 @@ -import VisualizationError from '../utils/visualization-error'; +import RenderError from '../utils/render-error'; const LOADED = {}; @@ -34,7 +34,7 @@ export async function load(name, version, { config }, loader) { if (__NEBULA_DEV__) { console.warn(e); // eslint-disable-line no-console } - throw new VisualizationError(`Failed to load visualization: '${sKey}'`, e); + throw new RenderError(`Failed to load visualization: '${sKey}'`, e); }); } diff --git a/apis/nucleus/src/utils/render-error.js b/apis/nucleus/src/utils/render-error.js new file mode 100644 index 000000000..3754a25e2 --- /dev/null +++ b/apis/nucleus/src/utils/render-error.js @@ -0,0 +1,15 @@ +/** + * @class RenderError + * @extends Error + * @param {string} message + * @param {Error} originalError + * @property {Error} originalError + */ + +export default class RenderError extends Error { + constructor(message, originalError) { + super(message); + this.originalError = originalError; + this.name = 'RenderError'; + } +} diff --git a/apis/nucleus/src/utils/visualization-error.js b/apis/nucleus/src/utils/visualization-error.js deleted file mode 100644 index 0886b427f..000000000 --- a/apis/nucleus/src/utils/visualization-error.js +++ /dev/null @@ -1,7 +0,0 @@ -export default class VisualizationError extends Error { - constructor(message, originalError) { - super(message); - this.originalError = originalError; - this.name = 'VisualizationError'; - } -} diff --git a/apis/stardust/api-spec/spec.json b/apis/stardust/api-spec/spec.json index fb8595e7a..495e0adc4 100644 --- a/apis/stardust/api-spec/spec.json +++ b/apis/stardust/api-spec/spec.json @@ -1767,7 +1767,11 @@ "description": "Callback function called if an error occurs", "optional": true, "kind": "function", - "params": [] + "params": [ + { + "type": "#/definitions/RenderError" + } + ] }, "plugins": { "description": "plugins passed into the visualisation", @@ -1914,6 +1918,32 @@ } } }, + "RenderError": { + "extends": [ + { + "type": "Error" + } + ], + "kind": "class", + "constructor": { + "kind": "function", + "params": [ + { + "name": "message", + "type": "string" + }, + { + "name": "originalError", + "type": "Error" + } + ] + }, + "entries": { + "originalError": { + "type": "Error" + } + } + }, "Navigation": { "stability": "experimental", "availability": { diff --git a/apis/stardust/types/index.d.ts b/apis/stardust/types/index.d.ts index 3601b82f8..1c115be3e 100644 --- a/apis/stardust/types/index.d.ts +++ b/apis/stardust/types/index.d.ts @@ -570,8 +570,9 @@ declare namespace stardust { onRender?(): void; /** * Callback function called if an error occurs + * @param $ */ - onError?(): void; + onError?($: stardust.RenderError): void; plugins?: stardust.Plugin[]; id?: string; type?: string; @@ -610,6 +611,13 @@ declare namespace stardust { meta?: object; } + class RenderError extends Error { + constructor(message: string, originalError: Error); + + originalError: Error; + + } + class Navigation implements stardust.Emitter { constructor(); diff --git a/test/mashup/visualize/life.html b/test/mashup/visualize/life.html index 1cdcdf62d..48d2957e0 100644 --- a/test/mashup/visualize/life.html +++ b/test/mashup/visualize/life.html @@ -44,7 +44,7 @@
-
+
diff --git a/test/mashup/visualize/life.int.js b/test/mashup/visualize/life.int.js index 56912b980..acc20e060 100644 --- a/test/mashup/visualize/life.int.js +++ b/test/mashup/visualize/life.int.js @@ -20,6 +20,10 @@ describe('object lifecycle', () => { '[data-tid="error-title"]', "Could not find a version of 'voooz' that supports current object version. Did you forget to register voooz?" ); + await waitForTextStatus( + '[data-tid="error-external"]', + "Could not find a version of 'voooz' that supports current object version. Did you forget to register voooz?" + ); }); it('should show spinner and requirements for known type', async () => { diff --git a/test/mashup/visualize/scenarios.js b/test/mashup/visualize/scenarios.js index 501758948..ae0195586 100644 --- a/test/mashup/visualize/scenarios.js +++ b/test/mashup/visualize/scenarios.js @@ -590,8 +590,10 @@ async function render() { const viz = await configuration(app).render({ element, id: 'bb8', - onError: () => { - // const errorElement = document.querySelector('.errors'); + onError: (e) => { + console.log(e); + const errorElement = document.querySelector('.errors'); + errorElement.textContent = e.message; }, });