You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust WASM函数Panic时JS未抛异常,如何让JS感知或触发异常?

解决Rust WASM panic时JS无法捕获异常的问题

方法一:自定义panic钩子触发JS异常

默认的console_error_panic_hook只会把panic信息输出到控制台,不会主动让JS抛出异常。你可以替换这个钩子,在panic发生时直接调用JS的抛出逻辑。

Rust代码示例:

use wasm_bindgen::prelude::*;
use std::panic;

#[wasm_bindgen(start)]
pub fn init() {
    // 替换默认panic钩子
    panic::set_hook(Box::new(|panic_info| {
        let err_msg = panic_info.to_string();
        // 调用JS的Error构造并抛出
        let _ = js_sys::Error::new(&err_msg).throw();
    }));
}

// 示例异步WASM函数
#[wasm_bindgen]
pub async fn async_wasm_task() -> Result<(), JsValue> {
    // 模拟panic场景
    panic!("WASM内部逻辑出错");
    Ok(())
}

JS侧调用时,就能通过try/catch捕获到异常,Promise也会正常进入reject状态:

import init, { async_wasm_task } from './your_wasm_module.js';

async function runTask() {
    await init();
    try {
        await async_wasm_task();
    } catch (err) {
        console.error("捕获到WASM panic:", err);
        // 这里处理错误逻辑
    }
}

runTask();

方法二:用Result封装所有对外函数

更稳妥的方式是避免Rust函数直接panic,把所有可能出错的逻辑用Result<T, JsValue>封装,手动将错误转换为JS可识别的错误值返回。

Rust代码示例:

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub async fn async_wasm_task() -> Result<(), JsValue> {
    // 把可能出错的逻辑包装成Result返回
    match risky_operation() {
        Ok(_) => Ok(()),
        Err(e) => Err(JsValue::from_str(&format!("WASM操作失败: {}", e))),
    }
}

fn risky_operation() -> Result<(), String> {
    // 模拟出错场景
    Err("参数不合法".to_string())
}

这种方式下,JS调用时Promise会自动reject,直接用catch处理即可,无需修改panic钩子。

注意点

  • 自定义panic钩子要在WASM初始化时就设置(比如用#[wasm_bindgen(start)]标记初始化函数),避免遗漏早期的panic。
  • 同步WASM函数的panic也能通过自定义钩子被JS的try/catch捕获,逻辑和异步场景一致。

内容的提问来源于stack exchange,提问作者Tadeo Hepperle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 22:12:35