From c9c7a958aee9981547ffd5d38c6530c7e3a09915 Mon Sep 17 00:00:00 2001 From: Twan van Laarhoven Date: Fri, 22 May 2020 00:30:18 +0200 Subject: [PATCH] Add exception handlers in places where scripts are invoked. This should lead to slightly nicer error messages. --- src/gui/set/keywords_panel.cpp | 10 +++++++--- src/gui/set/stats_panel.cpp | 16 ++++++++++------ src/gui/value/choice.cpp | 8 ++++++-- src/gui/value/color.cpp | 6 +++++- src/script/script_manager.cpp | 12 ++++++++++-- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/gui/set/keywords_panel.cpp b/src/gui/set/keywords_panel.cpp index de1b56be..7266af8f 100644 --- a/src/gui/set/keywords_panel.cpp +++ b/src/gui/set/keywords_panel.cpp @@ -246,9 +246,13 @@ String KeywordsPanel::runRefScript(int find_i) { } else { FOR_EACH(r, p->refer_scripts) { if (i++ == find_i) { - Context& ctx = set->getContext(); - ctx.setVariable(SCRIPT_VAR_input, to_script(param_s)); - return r->script.invoke(ctx)->toString(); + try { + Context& ctx = set->getContext(); + ctx.setVariable(SCRIPT_VAR_input, to_script(param_s)); + return r->script.invoke(ctx)->toString(); + } catch (ScriptError const& e) { + handle_error(ScriptError(e.what() + _("\n in keyword refer script '") + r->name + _("'"))); + } } } } diff --git a/src/gui/set/stats_panel.cpp b/src/gui/set/stats_panel.cpp index 438cba1f..99ec4df3 100644 --- a/src/gui/set/stats_panel.cpp +++ b/src/gui/set/stats_panel.cpp @@ -480,12 +480,16 @@ void StatsPanel::showCategory(const GraphType* prefer_layout) { GraphElementP e(new GraphElement(i)); bool show = true; FOR_EACH(dim, dims) { - String value = untag(dim->script.invoke(ctx)->toString()); - e->values.push_back(value); - if (value.empty() && !dim->show_empty) { - // don't show this element - show = false; - break; + try { + String value = untag(dim->script.invoke(ctx)->toString()); + e->values.push_back(value); + if (value.empty() && !dim->show_empty) { + // don't show this element + show = false; + break; + } + } catch (ScriptError const& e) { + handle_error(ScriptError(e.what() + _("\n in script for statistics dimension '") + dim->name + _("'"))); } } if (show) { diff --git a/src/gui/value/choice.cpp b/src/gui/value/choice.cpp index 49fb1319..561515ba 100644 --- a/src/gui/value/choice.cpp +++ b/src/gui/value/choice.cpp @@ -229,8 +229,12 @@ size_t DropDownChoiceList::selection() const { return 0; } else { // run default script to find out what the default choice would be - String default_choice = field().default_script.invoke( cve.viewer.getContext() )->toString(); - default_id = group->choiceId(default_choice); + try { + String default_choice = field().default_script.invoke( cve.viewer.getContext() )->toString(); + default_id = group->choiceId(default_choice); + } catch (ScriptError const& e) { + handle_error(ScriptError(e.what() + _("\n in default script for '") + field().name + _("'"))); + } } } // item corresponding to id diff --git a/src/gui/value/color.cpp b/src/gui/value/color.cpp index 930c1be7..5835deab 100644 --- a/src/gui/value/color.cpp +++ b/src/gui/value/color.cpp @@ -107,7 +107,11 @@ size_t DropDownColorList::selection() const { return 0; } else if (hasDefault()) { // evaluate script to find default color - default_color = field().default_script.invoke(cve.viewer.getContext())->toColor(); + try { + default_color = field().default_script.invoke(cve.viewer.getContext())->toColor(); + } catch (ScriptError const& e) { + handle_error(ScriptError(e.what() + _("\n in default script for '") + field().name + _("'"))); + } } return selection; } diff --git a/src/script/script_manager.cpp b/src/script/script_manager.cpp index 085d8546..e6a88927 100644 --- a/src/script/script_manager.cpp +++ b/src/script/script_manager.cpp @@ -44,8 +44,16 @@ Context& SetScriptContext::getContext(const StyleSheetP& stylesheet) { ctx.setVariable(SCRIPT_VAR_styling, to_script(&set.stylingDataFor(*stylesheet))); try { // perform init scripts, don't use a scope, variables stay bound in the context - set.game ->init_script.invoke(ctx, false); - stylesheet->init_script.invoke(ctx, false); + try { + set.game ->init_script.invoke(ctx, false); + } catch (const ScriptError& e) { + handle_error(ScriptError(e.what() + _("\n in init script for game ") + set.game->name())); + } + try { + stylesheet->init_script.invoke(ctx, false); + } catch (const ScriptError& e) { + handle_error(ScriptError(e.what() + _("\n in init script for stylesheet ") + stylesheet->name())); + } } catch (const Error& e) { handle_error(e); }