From 959c65dbb2c663c5b31ef58d4737b99faf6d1771 Mon Sep 17 00:00:00 2001 From: Jorijn van der Graaf Date: Tue, 20 Oct 2026 19:08:12 +0200 Subject: [PATCH] fix(script): a script that throws anything at all exits 1 RunScript caught std::exception only. Anything else a script threw went on across the project.so boundary, and crafter-build ended in std::terminate instead of reporting the script's failure. Co-Authored-By: Claude Opus 5.5 --- implementations/Crafter.Build-Script.cpp | 4 ++++ tests/Script/main.cpp | 2 ++ 2 files changed, 6 insertions(+) diff --git a/implementations/Crafter.Build-Script.cpp b/implementations/Crafter.Build-Script.cpp index 69fc677..3f902fc 100644 --- a/implementations/Crafter.Build-Script.cpp +++ b/implementations/Crafter.Build-Script.cpp @@ -96,5 +96,9 @@ returned; ctx.args holds the arguments.)msg"); Progress::Clear(); std::println(std::cerr, "script '{}' failed: {}", found->name, e.what()); return 1; + } catch (...) { + Progress::Clear(); + std::println(std::cerr, "script '{}' failed: it threw something that isn't a std::exception", found->name); + return 1; } } diff --git a/tests/Script/main.cpp b/tests/Script/main.cpp index 89e83fb..8e200a8 100644 --- a/tests/Script/main.cpp +++ b/tests/Script/main.cpp @@ -120,6 +120,8 @@ int main() { Configuration cfg; cfg.scripts.push_back({"throws", [](ScriptContext&) -> std::int32_t { throw std::runtime_error("no such tool"); }}); Check(RunScript(cfg, {.name = "throws", .named = true}) == 1, "a throwing script exits 1"); + cfg.scripts.push_back({"throwsInt", [](ScriptContext&) -> std::int32_t { throw 7; }}); + Check(RunScript(cfg, {.name = "throwsInt", .named = true}) == 1, "and so does one throwing something that isn't a std::exception"); } // Declarations that cannot work are refused before anything runs, also