From 0af87a2885f42b41388544ad5f5a6e7fa8893e13 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Sun, 24 Sep 2023 00:31:08 +0330 Subject: [PATCH] Add panic docs --- book/src/SUMMARY.md | 1 + .../panic_and_exceptions.md | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 book/src/call_rust_from_cpp/panic_and_exceptions.md diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 3915d60..a791bcb 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -8,6 +8,7 @@ - [Wellknown traits](./call_rust_from_cpp/wellknown_traits.md) - [Layout policy](./call_rust_from_cpp/layout_policy.md) - [Types with special support](./call_rust_from_cpp/special_types.md) + - [Panic and exceptions](./call_rust_from_cpp/panic_and_exceptions.md) - [Calling C++ from Rust](./call_cpp_from_rust/index.md) - [Calling C++ free functions](./call_cpp_from_rust/function.md) - [Adding methods to Rust types](./call_cpp_from_rust/rust_impl.md) diff --git a/book/src/call_rust_from_cpp/panic_and_exceptions.md b/book/src/call_rust_from_cpp/panic_and_exceptions.md new file mode 100644 index 0000000..92efc1a --- /dev/null +++ b/book/src/call_rust_from_cpp/panic_and_exceptions.md @@ -0,0 +1,37 @@ +# Panic and exceptions + +By default, Zngur aborts the process if an unwinding (Rust panic or C++ exception) reaches the cross language boundary. Handling +unwinding adds a non zero performance cost to every function call, and complicates things as catching an unwinding can result +in a corrupt state for some objects. (See [unwind safety](https://doc.rust-lang.org/std/panic/trait.UnwindSafe.html)) + +But Zngur has support for converting Rust panics into a C++ exception. To enable that, add + +``` +#convert_panic_to_exception +``` + +to your `main.zng` file. Now you can catch exceptions of kind `rust::Panic` for handling Rust panics: + +```C++ +try { + std::cout << "s[2] = " << *s.get(2).unwrap() << std::endl; + std::cout << "s[4] = " << *s.get(4).unwrap() << std::endl; +} catch (rust::Panic e) { + std::cout << "Rust panic happened" << std::endl; +} +``` + +assuming `s` contains `[2, 5, 7, 3]`, the above code prints: + +``` +s[2] = 7 +thread '' panicked at 'called `Option::unwrap()` on a `None` value', examples/simple/src/generated.rs:184:39 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +s[4] = Rust panic happened +``` + +To disable the the log, you need to register a panic hook in the Rust side (See [this stack overflow question](https://stackoverflow.com/questions/35559267/suppress-panic-output-in-rust-when-using-paniccatch-unwind)). Note that +the `rust::Panic` object contains nothing, and you will lose the panic message. + +For proper error handling, consider returning `Result` from your Rust functions, and throw native C++ exceptions with proper details in case of `Err` variant. Use +this panic to exception mechanism only in places which you need `catch_unwind` in Rust (e.g. for increasing fault tolerance).