Skip to content

Commit 4a0a916

Browse files
committed
Improve wasm errors
1 parent d3b2fa6 commit 4a0a916

File tree

1 file changed

+24
-27
lines changed

1 file changed

+24
-27
lines changed

wasm/lib/src/convert.rs

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,38 @@ use wasm_bindgen::{closure::Closure, prelude::*, JsCast};
55
use rustpython_vm::exceptions::PyBaseExceptionRef;
66
use rustpython_vm::function::PyFuncArgs;
77
use rustpython_vm::obj::{objbytes, objtype};
8-
use rustpython_vm::py_serde;
98
use rustpython_vm::pyobject::{ItemProtocol, PyObjectRef, PyResult, PyValue};
109
use rustpython_vm::VirtualMachine;
10+
use rustpython_vm::{exceptions, py_serde};
1111

1212
use crate::browser_module;
1313
use crate::vm_class::{stored_vm_from_wasm, WASMVirtualMachine};
1414

15-
pub fn py_err_to_js_err(vm: &VirtualMachine, py_err: &PyBaseExceptionRef) -> JsValue {
16-
macro_rules! map_exceptions {
17-
($py_exc:ident, $msg:expr, { $($py_exc_ty:expr => $js_err_new:expr),*$(,)? }) => {
18-
$(if objtype::isinstance($py_exc, $py_exc_ty) {
19-
JsValue::from($js_err_new($msg))
20-
} else)* {
21-
JsValue::from(js_sys::Error::new($msg))
22-
}
23-
};
15+
#[wasm_bindgen(inline_js = r"
16+
export class PyError extends Error {
17+
constructor(info) {
18+
const msg = info.args[0];
19+
if (typeof msg === 'string') super(msg);
20+
else super();
21+
this.info = info;
2422
}
25-
let msg = match vm.to_str(py_err.as_object()) {
26-
Ok(msg) => msg,
27-
Err(_) => return js_sys::Error::new("error getting error").into(),
28-
};
29-
let js_err = map_exceptions!(py_err, msg.as_str(), {
30-
// TypeError is sort of a catch-all for "this value isn't what I thought it was like"
31-
&vm.ctx.exceptions.type_error => js_sys::TypeError::new,
32-
&vm.ctx.exceptions.value_error => js_sys::TypeError::new,
33-
&vm.ctx.exceptions.index_error => js_sys::TypeError::new,
34-
&vm.ctx.exceptions.key_error => js_sys::TypeError::new,
35-
&vm.ctx.exceptions.attribute_error => js_sys::TypeError::new,
36-
&vm.ctx.exceptions.name_error => js_sys::ReferenceError::new,
37-
&vm.ctx.exceptions.syntax_error => js_sys::SyntaxError::new,
38-
});
39-
if let Some(tb) = py_err.traceback() {
40-
let _ = Reflect::set(&js_err, &"row".into(), &(tb.lineno as u32).into());
23+
get name() { return this.info.exc_type; }
24+
get traceback() { return this.info.traceback; }
25+
toString() { return this.info.rendered; }
26+
}
27+
")]
28+
extern "C" {
29+
type PyError;
30+
#[wasm_bindgen(constructor)]
31+
fn new(info: JsValue) -> PyError;
32+
}
33+
34+
pub fn py_err_to_js_err(vm: &VirtualMachine, py_err: &PyBaseExceptionRef) -> JsValue {
35+
let res = serde_wasm_bindgen::to_value(&exceptions::SerializeException::new(vm, py_err));
36+
match res {
37+
Ok(err_info) => PyError::new(err_info).into(),
38+
Err(e) => e.into(),
4139
}
42-
js_err
4340
}
4441

4542
pub fn js_py_typeerror(vm: &VirtualMachine, js_err: JsValue) -> PyBaseExceptionRef {

0 commit comments

Comments
 (0)