Browse Source

webassembly/proxy_c: Reject promises with a PythonError instance.

The `reason` in a rejected promise should be an instance of `Error`.  That
leads to better error messages on the JavaScript side.

Signed-off-by: Damien George <damien@micropython.org>
pull/14434/head
Damien George 6 months ago
parent
commit
9da63a343e
  1. 11
      ports/webassembly/proxy_c.c
  2. 11
      tests/ports/webassembly/run_python_async_error.mjs
  3. 5
      tests/ports/webassembly/run_python_async_error.mjs.exp

11
ports/webassembly/proxy_c.c

@ -297,7 +297,14 @@ EM_JS(void, js_then_resolve, (uint32_t * ret_value, uint32_t * resolve, uint32_t
});
EM_JS(void, js_then_reject, (uint32_t * ret_value, uint32_t * resolve, uint32_t * reject), {
const ret_value_js = proxy_convert_mp_to_js_obj_jsside(ret_value);
// The ret_value object should be a Python exception. Convert it to a
// JavaScript PythonError and pass it as the reason to reject the promise.
let ret_value_js;
try {
ret_value_js = proxy_convert_mp_to_js_obj_jsside(ret_value);
} catch(error) {
ret_value_js = error;
}
const resolve_js = proxy_convert_mp_to_js_obj_jsside(resolve);
const reject_js = proxy_convert_mp_to_js_obj_jsside(reject);
reject_js(ret_value_js);
@ -359,7 +366,7 @@ static mp_obj_t proxy_resume_execute(mp_obj_t self_in, mp_obj_t send_value, mp_o
} else { // ret_kind == MP_VM_RETURN_EXCEPTION;
// Pass the exception through as an object to reject the promise (don't raise/throw it).
uint32_t out_ret_value[PVN];
proxy_convert_mp_to_js_obj_cside(ret_value, out_ret_value);
proxy_convert_mp_to_js_exc_cside(ret_value, out_ret_value);
js_then_reject(out_ret_value, out_resolve, out_reject);
return mp_const_none;
}

11
tests/ports/webassembly/run_python_async_error.mjs

@ -0,0 +1,11 @@
// Test raising an exception in async Python code running in runPythonAsync,
// that the JavaScript-level promise is rejected with a PythonError.
const mp = await (await import(process.argv[2])).loadMicroPython();
try {
await mp.runPythonAsync("await fail");
} catch (error) {
console.log(error.name, error.type);
console.log(error.message);
}

5
tests/ports/webassembly/run_python_async_error.mjs.exp

@ -0,0 +1,5 @@
PythonError NameError
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'fail' isn't defined
Loading…
Cancel
Save