From 5be406e2dfccbb197354c377bf179351f0ee9db6 Mon Sep 17 00:00:00 2001 From: Sergey Kuznetsov Date: Wed, 29 Apr 2026 17:42:15 +0100 Subject: [PATCH] Add expample of panic handling --- crates/hello_world/src/lib.rs | 22 ++++++++++++++++++++-- src/test/basics/RustInterop_test.cpp | 11 +++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/crates/hello_world/src/lib.rs b/crates/hello_world/src/lib.rs index c7d8d59ae5..95db403a1e 100644 --- a/crates/hello_world/src/lib.rs +++ b/crates/hello_world/src/lib.rs @@ -11,6 +11,7 @@ mod ffi { extern "Rust" { type LoggerGuard; fn init_logger() -> Box; + fn safe_init_logger() -> Result>; fn hello_world() -> String; fn log_info(s: &str); } @@ -26,8 +27,7 @@ pub fn init_logger() -> Box { let (non_blocking, guard) = tracing_appender::non_blocking(std::io::stdout()); - let filter = EnvFilter::try_from_default_env() - .unwrap_or_else(|_| EnvFilter::new("info")); + let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")); fmt() .with_env_filter(filter) @@ -37,6 +37,24 @@ pub fn init_logger() -> Box { Box::new(LoggerGuard(guard)) } +fn safe_call(f: F) -> Result> +where + F: FnOnce() -> R + std::panic::UnwindSafe, +{ + std::panic::catch_unwind(f).map_err(|e| { + let msg = e + .downcast_ref::<&str>() + .map(|s| s.to_string()) + .or_else(|| e.downcast_ref::().cloned()) + .unwrap_or_else(|| "unknown panic".to_string()); + Box::::from(msg) + }) +} + +pub fn safe_init_logger() -> Result, Box> { + safe_call(init_logger) +} + pub fn hello_world() -> String { "hello_world".to_string() } diff --git a/src/test/basics/RustInterop_test.cpp b/src/test/basics/RustInterop_test.cpp index b1eceb354b..8181f40905 100644 --- a/src/test/basics/RustInterop_test.cpp +++ b/src/test/basics/RustInterop_test.cpp @@ -22,6 +22,17 @@ public: auto const guard = rs::hello_world::init_logger(); rs::hello_world::log_info("test log message from C++"); BEAST_EXPECT(true); + // Second init should panic; safe_init_logger catches it and throws. + bool caught = false; + try + { + rs::hello_world::safe_init_logger(); + } + catch (std::exception const&) + { + caught = true; + } + BEAST_EXPECT(caught); } void