In this example we'll see how to pattern match for the error and output the error message returned from Wasmer.
There will come a time when running a WebAssembly module will not work, and trying to figure out why it does not work can be a difficult task! In the current MVP of WebAssembly, debugging isn't explicitly defined for runtimes both in and out of the browser. So we'll have to write some error handling code ourselves.
In this example, we will load a WebAssembly module that purposely produces an error in its exported function call. The Host (our Rust application) will pattern match for the error and output the error message returned from Wasmer.
First we are going to want to initialize a new project. To do this we can navigate to our project folder, or create one. In this example, we will create a new project. Lets create it and navigate to it:
The final code for this example can be found on GitHub.
let div_by_zero = instance.exports.get_function("div_by_zero")?.native::<(), i32>()?;
let result = div_by_zero.call();
divByZero, err := instance.Exports.GetFunction("div_by_zero")
if err != nil {
panic(fmt.Sprintln("Failed to get the `div_by_zero` function:", err))
}
_, err = divByZero()
match result {
Ok(_) => {
panic!("throw_wasm_error did not error");
},
Err(e) => {
println!("Error caught from `div_by_zero`: {}", e.message());
let frames = e.trace();
let frames_len = frames.len();
for i in 0..frames_len {
println!(
" Frame #{}: {:?}::{:?}",
frames_len - i,
frames[i].module_name(),
frames[i].function_name().or(Some("<func>")).unwrap()
);
}
}
}
if err == nil {
panic(fmt.Sprintln("`div_by_zero` did not error"))
}
fmt.Println("Error caught from `div_by_zero`:", err)
trap, ok := err.(*wasmer.TrapError)
if !ok {
panic(fmt.Sprintln("Error was not of the expected type"))
}
frames := trap.Trace()
framesLen := len(frames)
for index, frame := range frames {
fmt.Printf(
" Frame #%d: function index: %d\n",
framesLen - index,
frame.FunctionIndex()
)
}
Compiling module...
Instantiating module...
Calling `div_by_zero` function...
Error caught from `div_by_zero`: integer divide by zero
Frame #2: "<module>"::"do_div_by_zero_f"
Frame #1: "<module>"::"div_by_zero_f"
git clone https://github.com/wasmerio/wasmer.git
cd wasmer
cargo run --example errors --release --features "cranelift"
Compiling module...
Instantiating module...
Calling `div_by_zero` function...
Error caught from `div_by_zero`: integer divide by zero
Frame #2: function index: 0
Frame #1: function index: 50
git clone https://github.com/wasmerio/wasmer-go.git
cd wasmer-go
go test examples/example_errors_test.go