Search code examples
javascriptrustwebassembly

JavaScript code calls Rust WASM function that panics: No exception thrown


I have a web app where some JavaScript code calls into a WASM module written in Rust. I am using wasm_bindgen and console_error_panic_hook. When a Rust function panics, I get errors logged to the console, however no exception is thrown in JavaScript. This causes my async JavaScript functions Promise to never return.

Is there any way to get an exception thrown when a panic occurs?

Or is there another way, by which the Javascript code can know, that the rust function in the WASM panicked?


Solution

  • Currently, Rust as compiled to wasm32-unknown-unknown with wasm-bindgen does not support doing anything sensible with panics. In fact, the behavior is incoherent; panicking will cancel Wasm execution and return control to JavaScript (supposing a non-async call), and yet a future JS-to-Wasm call can re-enter the Rust Wasm module even though no unwinding has happened, and even though Rust code might have intentionally aborted — a potentially unsound behavior.

    (The easiest way to see this is to export a struct or callback containing a RefCell — if you .borrow_mut() the RefCell, and panic while holding the RefMut guard, then on the next call the RefCell will claim it is already borrowed, revealing that the RefMut guard was not dropped.)

    Hopefully the behavior will be improved, but for now, you should write your code to avoid panicking in any situation which you might want to recover from, and if there is a panic, treat it as a reason to reload the entire Wasm module (maybe reload the page) rather than attempting to continue with anything.