我尝试使用panic::catch_unwind
来捕获一些错误,但似乎没有用,并且有一个例子:
锈:
use std::{sync::Mutex};
use wasm_bindgen::prelude::*;
use std::sync::PoisonError;
use std::panic;
pub struct CurrentStatus {
pub index: i32,
}
#[wasm_bindgen]
extern {
pub fn alert(s: &str);
}
impl CurrentStatus {
fn new() -> Self {
CurrentStatus {
index: 1,
}
}
fn get_index(&mut self) -> i32 {
self.index += 1;
self.index.clone()
}
fn add_index(&mut self) {
self.index += 2;
}
}
lazy_static! {
pub static ref FOO: Mutex<CurrentStatus> = Mutex::new(CurrentStatus::new());
}
unsafe impl Send for CurrentStatus {}
#[wasm_bindgen]
pub fn add_index() {
FOO.lock().unwrap_or_else(PoisonError::into_inner).add_index();
}
#[wasm_bindgen]
pub fn get_index() -> i32 {
let mut foo = FOO.lock().unwrap_or_else(PoisonError::into_inner);
let result = panic::catch_unwind(|| {
panic!("error happen!"); // original panic! code
});
if result.is_err() {
alert("panic!!!!!panic");
}
return foo.get_index();
}
.js:
const js = import("../pkg/hello_wasm.js");
js.then(js => {
window.js = js;
console.log(js.get_index());
js.add_index();
});
我认为它应该引起恐慌,然后我可以打电话给add_index
。
但事实上,在恐慌之后,我既不能打电话。
我希望我能从一个函数中捕捉到恐慌,这样当用户调用其他函数时就可以了。
非常感谢
默认情况下 wasm 构建设置为panic=abort
,即即使有catch_unwind
也退出程序。
可以在此 pr 起设置panic=unwind
,但仅适用于[no_std]
板条箱。
如果你真的需要,有一些方法可以破解它,例如wasm-bindgen自己的测试箱通过使用scoped-tls
来捕捉恐慌,它看起来像这样:
scoped_tls::scoped_thread_local!(static CURRENT_OUTPUT: RefCell<Output>);
static SET_HOOK: Once = Once::new();
SET_HOOK.call_once(|| {
std::panic::set_hook(Box::new(|panic_info| {
let should_panic = CURRENT_OUTPUT.with(|output| {
let mut output = output.borrow_mut();
output.panic.push_str(&panic_info.to_string());
output.should_panic
});
if !should_panic {
console_error_panic_hook::hook(panic_info);
}
}));
});
let result = CURRENT_OUTPUT.set(&output, || {
let mut test = Some(test);
__wbg_test_invoke(&mut || {
let test = test.take().unwrap_throw();
future_output = Some(test.poll(cx))
})
});