From 145efe67c31e225c98af9840af34b7fd49d2e9a6 Mon Sep 17 00:00:00 2001 From: azivner Date: Fri, 17 Aug 2018 11:31:42 +0200 Subject: [PATCH] better logging and notifications on script errors for easier debugging --- src/public/javascripts/services/bundle.js | 12 +++++++++--- src/public/javascripts/services/info.js | 7 +++++++ src/public/javascripts/services/script_api.js | 7 ++++++- src/routes/api/script.js | 11 ++++++++--- src/services/script.js | 14 ++++++++++---- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/public/javascripts/services/bundle.js b/src/public/javascripts/services/bundle.js index e4f1819c8..60a9fe992 100644 --- a/src/public/javascripts/services/bundle.js +++ b/src/public/javascripts/services/bundle.js @@ -1,5 +1,6 @@ import ScriptContext from "./script_context.js"; import server from "./server.js"; +import infoService from "./info.js"; async function getAndExecuteBundle(noteId, originEntity = null) { const bundle = await server.get('script/bundle/' + noteId); @@ -10,9 +11,14 @@ async function getAndExecuteBundle(noteId, originEntity = null) { async function executeBundle(bundle, originEntity) { const apiContext = ScriptContext(bundle.note, bundle.allNotes, originEntity); - return await (function () { - return eval(`const apiContext = this; (async function() { ${bundle.script}\r\n})()`); - }.call(apiContext)); + try { + return await (function () { + return eval(`const apiContext = this; (async function() { ${bundle.script}\r\n})()`); + }.call(apiContext)); + } + catch (e) { + infoService.showAndLogError(`Execution of script "${bundle.note.title}" (${bundle.note.noteId}) failed with error: ${e.message}`); + } } async function executeStartupBundles() { diff --git a/src/public/javascripts/services/info.js b/src/public/javascripts/services/info.js index 91e1ef261..d48ddaf3c 100644 --- a/src/public/javascripts/services/info.js +++ b/src/public/javascripts/services/info.js @@ -14,6 +14,12 @@ function showMessage(message) { }); } +function showAndLogError(message, delay = 10000) { + showError(message, delay); + + messagingService.logError(message); +} + function showError(message, delay = 10000) { console.log(utils.now(), "error: ", message); @@ -36,5 +42,6 @@ function throwError(message) { export default { showMessage, showError, + showAndLogError, throwError } \ No newline at end of file diff --git a/src/public/javascripts/services/script_api.js b/src/public/javascripts/services/script_api.js index 2b1ee2284..23b82bed0 100644 --- a/src/public/javascripts/services/script_api.js +++ b/src/public/javascripts/services/script_api.js @@ -72,7 +72,12 @@ function ScriptApi(startNote, currentNote, originEntity = null) { originEntityId: originEntity ? originEntity.noteId : null }); - return ret.executionResult; + if (ret.success) { + return ret.executionResult; + } + else { + throw new Error("server error: " + ret.error); + } } return { diff --git a/src/routes/api/script.js b/src/routes/api/script.js index 6e998444a..b00e4ccb5 100644 --- a/src/routes/api/script.js +++ b/src/routes/api/script.js @@ -5,10 +5,15 @@ const attributeService = require('../../services/attributes'); const repository = require('../../services/repository'); async function exec(req) { - const result = await scriptService.executeScript(req.body.script, req.body.params, req.body.startNoteId, - req.body.currentNoteId, req.body.originEntityName, req.body.originEntityId); + try { + const result = await scriptService.executeScript(req.body.script, req.body.params, req.body.startNoteId, + req.body.currentNoteId, req.body.originEntityName, req.body.originEntityId); - return { executionResult: result }; + return { success: true, executionResult: result }; + } + catch (e) { + return { success: false, error: e.message }; + } } async function run(req) { diff --git a/src/services/script.js b/src/services/script.js index c820e058d..c64dc9317 100644 --- a/src/services/script.js +++ b/src/services/script.js @@ -3,6 +3,7 @@ const ScriptContext = require('./script_context'); const repository = require('./repository'); const cls = require('./cls'); const sourceIdService = require('./source_id'); +const log = require('./log'); async function executeNote(note, originEntity) { if (!note.isJavaScript()) { @@ -25,11 +26,16 @@ async function executeBundle(bundle, startNote, originEntity = null) { const ctx = new ScriptContext(startNote, bundle.allNotes, originEntity); - if (await bundle.note.hasLabel('manualTransactionHandling')) { - return await execute(ctx, script, ''); + try { + if (await bundle.note.hasLabel('manualTransactionHandling')) { + return await execute(ctx, script, ''); + } + else { + return await sql.transactional(async () => await execute(ctx, script, '')); + } } - else { - return await sql.transactional(async () => await execute(ctx, script, '')); + catch (e) { + log.error(`Execution of script "${bundle.note.title}" (${bundle.note.noteId}) failed with error: ${e.message}`); } }