From 4843149b6ac82754e7a4e1c983f2a90b8f735d8d Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 5 Mar 2019 20:46:23 +1100 Subject: [PATCH] Make error description available as "%val{error}" during catch blocks Fixes #2761 --- doc/pages/commands.asciidoc | 4 +++- src/commands.cc | 17 +++++++++++++---- test/compose/catch-error-desc/cmd | 1 + test/compose/catch-error-desc/in | 1 + test/compose/catch-error-desc/out | 1 + test/compose/catch-error-desc/rc | 1 + 6 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 test/compose/catch-error-desc/cmd create mode 100644 test/compose/catch-error-desc/in create mode 100644 test/compose/catch-error-desc/out create mode 100644 test/compose/catch-error-desc/rc diff --git a/doc/pages/commands.asciidoc b/doc/pages/commands.asciidoc index f24be1a9..db7d1834 100644 --- a/doc/pages/commands.asciidoc +++ b/doc/pages/commands.asciidoc @@ -278,7 +278,9 @@ but not really useful in that context. done on error, the catch part can be omitted. If an error is raised in the *on_error_commands*, that error is propagated, except if another *catch* and *on_error_commands* parameter follows, in which - case those commands get executed, and so-on. + case those commands get executed, and so-on. During error commands, + the description of the last raiser error is available as `$kak_error` + in the shell, or `%val{error}` in commands. *nop*:: does nothing, but arguments will be evaluated (e.g. shell expansion) diff --git a/src/commands.cc b/src/commands.cc index 5f7e1530..0e099b09 100644 --- a/src/commands.cc +++ b/src/commands.cc @@ -2080,17 +2080,26 @@ const CommandDesc try_catch_cmd = { } CommandManager& command_manager = CommandManager::instance(); + Optional shell_context_with_error; for (size_t i = 0; i < parser.positional_count(); i += 2) { if (i == 0 or i < parser.positional_count() - 1) { - try { - command_manager.execute(parser[i], context, shell_context); + try + { + command_manager.execute(parser[i], context, + shell_context_with_error.value_or(shell_context)); return; - } catch (runtime_error&) {} + } + catch (const runtime_error& error) + { + shell_context_with_error.emplace(shell_context); + shell_context_with_error->env_vars[StringView{"error"}] = error.what().str(); + } } else - command_manager.execute(parser[i], context, shell_context); + command_manager.execute(parser[i], context, + shell_context_with_error.value_or(shell_context)); } } }; diff --git a/test/compose/catch-error-desc/cmd b/test/compose/catch-error-desc/cmd new file mode 100644 index 00000000..d41464ed --- /dev/null +++ b/test/compose/catch-error-desc/cmd @@ -0,0 +1 @@ +:error diff --git a/test/compose/catch-error-desc/in b/test/compose/catch-error-desc/in new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/test/compose/catch-error-desc/in @@ -0,0 +1 @@ + diff --git a/test/compose/catch-error-desc/out b/test/compose/catch-error-desc/out new file mode 100644 index 00000000..43fd3e4b --- /dev/null +++ b/test/compose/catch-error-desc/out @@ -0,0 +1 @@ +no such command: 'non-existing-command' diff --git a/test/compose/catch-error-desc/rc b/test/compose/catch-error-desc/rc new file mode 100644 index 00000000..82bde5dd --- /dev/null +++ b/test/compose/catch-error-desc/rc @@ -0,0 +1 @@ +define-command error %{ try %{ non-existing-command } catch %{ exec i "%val{error}" } }