From 744b5a6f15b3a779c285bacabb505ed1c4345c64 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <piotr.gawron@uni.lu> Date: Thu, 4 Apr 2019 15:25:32 +0200 Subject: [PATCH] when plugin listener crash system notifies user and plugin about a problem --- CHANGELOG | 2 ++ .../src/main/js/plugin/MinervaPluginProxy.js | 24 ++++++++++++++++--- frontend-js/src/main/js/plugin/Plugin.js | 1 + frontend-js/src/test/js/plugin/Plugin-test.js | 11 +++++++++ ...rash.js&version=0.0.1&token=MOCK_TOKEN_ID& | 8 +++++++ .../testFiles/plugin/listener-crash.js | 23 ++++++++++++++++++ 6 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 frontend-js/testFiles/apiCalls/plugins/POST_hash=a794c40b7ed8f56406f66f2913543915&isPublic=false&name=test%20plugin&url=.%2FtestFiles%2Fplugin%2Flistener-crash.js&version=0.0.1&token=MOCK_TOKEN_ID& create mode 100644 frontend-js/testFiles/plugin/listener-crash.js diff --git a/CHANGELOG b/CHANGELOG index 420f5aab10..08487c32b0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -31,6 +31,8 @@ minerva (12.3.0~alpha.0) unstable; urgency=low (#591) * Small improvement: uploading sbml file should automatically discover a file type (#784) + * Small improvement: when plugin listeners crash the system notifies user + about problem with a plugin (#767) * Bug fix: progress bar of gene genome mapping upload is refreshing properly (#728) * Bug fix: when editing project Disease and Organism could not be removed diff --git a/frontend-js/src/main/js/plugin/MinervaPluginProxy.js b/frontend-js/src/main/js/plugin/MinervaPluginProxy.js index 1e1b8673c4..feb8595972 100644 --- a/frontend-js/src/main/js/plugin/MinervaPluginProxy.js +++ b/frontend-js/src/main/js/plugin/MinervaPluginProxy.js @@ -12,6 +12,8 @@ var Configuration = require('../Configuration'); var Bounds = require('../map/canvas/Bounds'); var Point = require('../map/canvas/Point'); +var GuiConnector = require('../GuiConnector'); + // noinspection JSUnusedLocalSymbols var logger = require('../logger'); @@ -453,7 +455,7 @@ function createProjectMap(options) { return dbOverlay.searchByQuery(params.query, params.perfect, params.fitBounds); } else if (dbOverlay instanceof SearchDbOverlay) { var zoom = params.zoom; - if (zoom ===undefined) { + if (zoom === undefined) { zoom = map.getSubmapById(params.modelId).getZoom(); } return dbOverlay.searchByCoordinates({ @@ -582,10 +584,26 @@ function createProjectMap(options) { throw new Error("Invalid argument"); } + var wrapper = function (e) { + try { + return Promise.resolve(listenerWrapper(e)).catch(function (error) { + GuiConnector.warn("Plugin " + options.plugin.getName() + " crashed"); + if (typeof options.plugin.getLoadedPluginData().notifyError === "function") { + options.plugin.getLoadedPluginData().notifyError({listener: param, data: e, error: error}); + } + }); + } catch (error) { + GuiConnector.warn("Plugin " + options.plugin.getName() + " crashed"); + if (typeof options.plugin.getLoadedPluginData().notifyError === "function") { + options.plugin.getLoadedPluginData().notifyError({listener: param, data: e, error: error}); + } + } + }; + for (var i = 0; i < objects.length; i++) { var object = objects[i]; - object.addListener(listenerType, listenerWrapper); - listenersData.push({listener: param.callback, wrapper: listenerWrapper, object: object, type: listenerType}); + object.addListener(listenerType, wrapper); + listenersData.push({listener: param.callback, wrapper: wrapper, object: object, type: listenerType}); } }, /** diff --git a/frontend-js/src/main/js/plugin/Plugin.js b/frontend-js/src/main/js/plugin/Plugin.js index 409d9d68c7..c513e2839d 100644 --- a/frontend-js/src/main/js/plugin/Plugin.js +++ b/frontend-js/src/main/js/plugin/Plugin.js @@ -24,6 +24,7 @@ var pluginId = 0; * @typedef {Object} UserPluginObject * @property {function(Object):void} register * @property {function():void} unregister + * @property {function(Object):void} [notifyError] * @property {function():string} getName * @property {function():string} getVersion * @property {function():(number|string)|number|string} minWidth diff --git a/frontend-js/src/test/js/plugin/Plugin-test.js b/frontend-js/src/test/js/plugin/Plugin-test.js index adbf4c9685..ac0671033a 100644 --- a/frontend-js/src/test/js/plugin/Plugin-test.js +++ b/frontend-js/src/test/js/plugin/Plugin-test.js @@ -5,6 +5,7 @@ require("../mocha-config"); // noinspection JSUnusedLocalSymbols var Promise = require("bluebird"); var Plugin = require('../../../main/js/plugin/Plugin'); +var Point = require('../../../main/js/map/canvas/Point'); var ServerConnector = require('../ServerConnector-mock'); var logger = require('../logger'); @@ -106,4 +107,14 @@ describe('Plugin', function () { }); }); }); + it('plugin listener crash', function () { + var map = helper.createCustomMap(); + + var plugin = createPlugin("./testFiles/plugin/listener-crash.js", map); + return plugin.load().then(function () { + return map.callListeners("onCenterChanged", new Point(0, 0)); + }).then(function () { + assert.equal(1, logger.getWarnings().length); + }); + }); }); diff --git a/frontend-js/testFiles/apiCalls/plugins/POST_hash=a794c40b7ed8f56406f66f2913543915&isPublic=false&name=test%20plugin&url=.%2FtestFiles%2Fplugin%2Flistener-crash.js&version=0.0.1&token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/plugins/POST_hash=a794c40b7ed8f56406f66f2913543915&isPublic=false&name=test%20plugin&url=.%2FtestFiles%2Fplugin%2Flistener-crash.js&version=0.0.1&token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000..02a0838194 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/plugins/POST_hash=a794c40b7ed8f56406f66f2913543915&isPublic=false&name=test%20plugin&url=.%2FtestFiles%2Fplugin%2Flistener-crash.js&version=0.0.1&token=MOCK_TOKEN_ID& @@ -0,0 +1,8 @@ +{ + "hash": "d5d652ac0e0f6467d4cb6a742f99d3f7", + "name": "test plugin", + "urls": [ + "./testFiles/plugin-invalid/invalid_register.js" + ], + "version": "0.0.1" +} \ No newline at end of file diff --git a/frontend-js/testFiles/plugin/listener-crash.js b/frontend-js/testFiles/plugin/listener-crash.js new file mode 100644 index 0000000000..d93a9d0a89 --- /dev/null +++ b/frontend-js/testFiles/plugin/listener-crash.js @@ -0,0 +1,23 @@ +minervaDefine(function () { + return { + register: function (minervaObject) { + var options = { + object: "map", + type: "onCenterChanged", + callback: function () { + throw new Error("Let's crash"); + } + }; + minervaObject.project.map.addListener(options); + }, + unregister: function () { + console.log("unregistering test plugin"); + }, + getName: function () { + return "test plugin"; + }, + getVersion: function () { + return "0.0.1"; + } + }; +}); \ No newline at end of file -- GitLab