← Back to Lessons Lesson 17 of 28
Intermediate getting-started
Error Handling in Wasm
Why Error Handling Matters in Wasm
When Rust panics in Wasm, the browser shows a cryptic unreachable error. Proper error handling converts Rust errors into meaningful JavaScript exceptions.
The Two Approaches
1. Result<T, JsValue> — Errors become JS exceptions
#[wasm_bindgen]
pub fn safe_divide(a: f64, b: f64) -> Result<f64, JsValue> {
if b == 0.0 {
Err(JsValue::from_str("Division by zero"))
} else {
Ok(a / b)
}
}In JavaScript:
try {
const result = safe_divide(10, 0);
} catch (e) {
console.error(e); // "Division by zero"
}2. Option<T> — Returns undefined on failure
#[wasm_bindgen]
pub fn find_user(id: u32) -> Option<String> {
if id == 1 { Some("Alice".to_string()) } else { None }
}In JavaScript:
const user = find_user(99);
if (user === undefined) {
console.log("User not found");
}Converting Between Error Types
The ? operator works with Result, but Wasm needs JsValue errors:
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn parse_and_double(input: &str) -> Result<i32, JsValue> {
let num: i32 = input.parse()
.map_err(|e: std::num::ParseIntError| {
JsValue::from_str(&format!("Parse error: {}", e))
})?;
Ok(num * 2)
}Custom Error Types
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct WasmError {
code: u32,
message: String,
}
#[wasm_bindgen]
impl WasmError {
pub fn code(&self) -> u32 { self.code }
pub fn message(&self) -> String { self.message.clone() }
}
fn make_error(code: u32, msg: &str) -> JsValue {
let err = WasmError { code, message: msg.to_string() };
JsValue::from(err)
}Panic Hook — Last Resort
For panics you can't prevent, install the panic hook to get readable messages:
use console_error_panic_hook;
#[wasm_bindgen(start)]
pub fn init() {
console_error_panic_hook::set_once();
}Without it: RuntimeError: unreachable
With it: panicked at 'index out of bounds: the len is 3 but the index is 5'
Best Practices
| Do | Don't |
|---|---|
Return Result<T, JsValue> from exported functions |
Let functions panic |
Use ? with .map_err() to convert errors |
Use .unwrap() in exported functions |
Install console_error_panic_hook |
Ignore panics |
| Give meaningful error messages | Return generic "error occurred" |
Use Option<T> for "not found" cases |
Return sentinel values (-1, empty string) |
Try It
Click Run to see the error handling patterns in action. Notice how each error type produces a clear, descriptive message.
Try It
Chapter Quiz
Pass all questions to complete this lesson