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 [`Store::take_pending_exception`]. 33 /// 34 /// [`Store::take_pending_exception`]: crate::Store::take_pending_exception 35 /// 36 /// Wasmtime uses an error type *without* payload, and stores the 37 /// exception itself on the store, to maintain proper GC rooting; 38 /// otherwise, it is difficult to get exception propagation up the 39 /// stack right in the presence of nested handle scopes. A pending 40 /// exception on the store is safely rooted as long as it is stored 41 /// there. 42 #[derive(Debug)] 43 pub struct ThrownException; 44 45 /// We need to implement Error for `ThrownException` so it can be boxed up into 46 /// a `wasmtime::Error`. 47 impl core::error::Error for ThrownException {} 48 49 /// `Error` requires `Display`. 50 impl core::fmt::Display for ThrownException { fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result51 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 52 write!(f, "thrown Wasm exception") 53 } 54 } 55