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>
This commit is contained in:
@@ -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), {
|
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 resolve_js = proxy_convert_mp_to_js_obj_jsside(resolve);
|
||||||
const reject_js = proxy_convert_mp_to_js_obj_jsside(reject);
|
const reject_js = proxy_convert_mp_to_js_obj_jsside(reject);
|
||||||
reject_js(ret_value_js);
|
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;
|
} else { // ret_kind == MP_VM_RETURN_EXCEPTION;
|
||||||
// Pass the exception through as an object to reject the promise (don't raise/throw it).
|
// Pass the exception through as an object to reject the promise (don't raise/throw it).
|
||||||
uint32_t out_ret_value[PVN];
|
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);
|
js_then_reject(out_ret_value, out_resolve, out_reject);
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
|
|||||||
11
tests/ports/webassembly/run_python_async_error.mjs
Normal file
11
tests/ports/webassembly/run_python_async_error.mjs
Normal file
@@ -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
Normal file
5
tests/ports/webassembly/run_python_async_error.mjs.exp
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
PythonError NameError
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
NameError: name 'fail' isn't defined
|
||||||
|
|
||||||
Reference in New Issue
Block a user