1 //! Types for the public API around exceptions. 2 //! 3 //! To allow host code to interact with exceptions, Wasmtime provides 4 //! two basic areas of API: 5 //! 6 //! - The [`crate::ExnRef`] type and associated types allow the host 7 //! to create exception objects. In the Wasm execution model, every 8 //! thrown exception is a unique instance of an exception object, 9 //! which carries a reference to the associated tag and any payload 10 //! values specified by the exception's signature. 11 //! 12 //! - The [`crate::Store::throw`] method to throw an exception, and 13 //! associated methods to take ([`crate::Store::take_exception`]) or 14 //! peek at ([`crate::Store::peek_exception`]) a thrown exception, 15 //! along with the `Error` type [`ThrownException`] that indicates 16 //! an exception is being thrown. This API allows access to a 17 //! "pending exception" slot on the `Store` which roots an exception 18 //! object and allows it to be propagated through Wasm and hostcall 19 //! layers. If Wasm code throws an uncaught exception, it will be 20 //! set as the pending exception and the call into Wasm will return 21 //! an `Err(ThrownException.into())`; if a hostcall wishes to throw 22 //! an exception to be caught by Wasm (or the outer call into Wasm 23 //! by the host), it can call `Store::throw` and return the 24 //! associated error. 25 26 /// An error type that represents that a pending WebAssembly exception 27 /// is set on the associated `Store`. 28 /// 29 /// When used as an error type and returned from a Wasm-to-host call, 30 /// or host-to-Wasm call, it indicates that the caller should either 31 /// continue propagating the error upward, or take and handle the 32 /// exception using [`crate::Store::take_exception`] (or a helper such 33 /// as [`crate::Store::catch`]. 34 /// 35 /// Wasmtime uses an error type *without* payload, and stores the 36 /// exception itself on the store, to maintain proper GC rooting; 37 /// otherwise, it is difficult to get exception propagation up the 38 /// stack right in the presence of nested handle scopes. A pending 39 /// exception on the store is safely rooted as long as it is stored 40 /// there. 41 #[derive(Debug)] 42 pub struct ThrownException; 43 44 /// We need to implement Error for `ThrownException` so it can be boxed up into an `anyhow::Error`. 45 impl core::error::Error for ThrownException {} 46 47 /// `Error` requires `Display`. 48 impl core::fmt::Display for ThrownException { 49 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 50 write!(f, "thrown Wasm exception") 51 } 52 } 53