From 1df3becdb220c3b39528d6bea2460837de871558 Mon Sep 17 00:00:00 2001 From: udo Date: Sat, 18 Jul 2026 16:59:14 +0000 Subject: [PATCH] Fail unresolved unit renders with HTTP 500 --- site/doc/pages/unit_render.txt | 2 ++ site/tests/cli_runner.uce | 5 +++++ site/tests/unit_failure.uce | 4 ++++ src/wasm/core.cpp | 1 + 4 files changed, 12 insertions(+) create mode 100644 site/tests/unit_failure.uce diff --git a/site/doc/pages/unit_render.txt b/site/doc/pages/unit_render.txt index e59cf43..a42760f 100644 --- a/site/doc/pages/unit_render.txt +++ b/site/doc/pages/unit_render.txt @@ -18,6 +18,8 @@ Calls another UCE file and executes its `RENDER(Request& context)` function. If `context` is omitted, the current active request context is used. +Calling a missing unit or render handler is a server error and sets HTTP status 500. If a unit is intentionally optional, inspect it with `unit_info()` before calling `unit_render()`. + Examples: diff --git a/site/tests/cli_runner.uce b/site/tests/cli_runner.uce index c18f6eb..23b74eb 100644 --- a/site/tests/cli_runner.uce +++ b/site/tests/cli_runner.uce @@ -329,6 +329,11 @@ void cli_run_site_suite(bool skip_local_service_pages = false) void cli_run_security_smoke() { + CliHttpResponse missing_unit = cli_frontend("/tests/unit_failure.uce"); + cli_test_case("uce_unit_failure:unit_render missing target is HTTP 500", + missing_unit.status == 500 && cli_contains(missing_unit.body, "unit not found: does-not-exist.uce"), + "status=" + std::to_string(missing_unit.status) + " body=" + cli_truncate(missing_unit.body)); + CliHttpResponse missing_component = cli_frontend("/tests/component_failure.uce"); cli_test_case("uce_component_failure:component_render missing target is HTTP 500", missing_component.status == 500 && cli_contains(missing_component.body, "component not found: components/does-not-exist"), diff --git a/site/tests/unit_failure.uce b/site/tests/unit_failure.uce new file mode 100644 index 0000000..7f92e4d --- /dev/null +++ b/site/tests/unit_failure.uce @@ -0,0 +1,4 @@ +RENDER(Request& context) +{ + unit_render("does-not-exist.uce", context); +} diff --git a/src/wasm/core.cpp b/src/wasm/core.cpp index e3f009a..b7c2690 100644 --- a/src/wasm/core.cpp +++ b/src/wasm/core.cpp @@ -727,6 +727,7 @@ void unit_render(String file_name, Request& request) s32 slot = wasm_resolve_target(unit_name, handler, &resolved); if(!slot) { + request.set_status(500, "Internal Server Error"); print(component_error_banner("unit not found: " + trim(file_name))); return; }