litelib_initialize_new, litelib_initialize_new_from_phrase,
litelib_initialize_existing and litelib_check_server_online had no
catch_unwind (only litelib_execute did), so any panic below them
unwound across the C ABI into the GUI. With rustc 1.63 that is
undefined behaviour; in practice the process aborts with "fatal runtime
error: failed to initiate panic, error 5". The simplest trigger is a
malformed user-entered server URL: get_server_or_default unwraps the
http::Uri parse before anything else runs.
- ffi_guard (next to error_cstring) runs a body under catch_unwind and
turns a panic into "Error: Rust panic in <name>", which the C++ bridge
already treats as a failed call. The three init entry points keep
their extern signatures and #[no_mangle] and call ffi_guard; their old
bodies are now private *_impl functions.
- litelib_check_server_online wraps its body the same way and returns
false on a panic.
- litelib_initialize_existing opens the wallet through
read_from_disk_reporting. After a recovery from the .bak it returns
"OK: recovered from backup; damaged file kept as <name>" instead of
"OK". The C++ side treats any non-empty, non-error string as a
successful open, so this is ABI-compatible.
No ABI or symbol change: the exported symbol inventory
(lite-backend-symbols.txt) is identical. panic = "unwind" stays in the
release profile, and every guard depends on it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>