Skip to content

Commit 9da63a3

Browse files
committed
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>
1 parent 9681a66 commit 9da63a3

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

ports/webassembly/proxy_c.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,14 @@ EM_JS(void, js_then_resolve, (uint32_t * ret_value, uint32_t * resolve, uint32_t
297297
});
298298

299299
EM_JS(void, js_then_reject, (uint32_t * ret_value, uint32_t * resolve, uint32_t * reject), {
300-
const ret_value_js = proxy_convert_mp_to_js_obj_jsside(ret_value);
300+
// The ret_value object should be a Python exception. Convert it to a
301+
// JavaScript PythonError and pass it as the reason to reject the promise.
302+
let ret_value_js;
303+
try {
304+
ret_value_js = proxy_convert_mp_to_js_obj_jsside(ret_value);
305+
} catch(error) {
306+
ret_value_js = error;
307+
}
301308
const resolve_js = proxy_convert_mp_to_js_obj_jsside(resolve);
302309
const reject_js = proxy_convert_mp_to_js_obj_jsside(reject);
303310
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
359366
} else { // ret_kind == MP_VM_RETURN_EXCEPTION;
360367
// Pass the exception through as an object to reject the promise (don't raise/throw it).
361368
uint32_t out_ret_value[PVN];
362-
proxy_convert_mp_to_js_obj_cside(ret_value, out_ret_value);
369+
proxy_convert_mp_to_js_exc_cside(ret_value, out_ret_value);
363370
js_then_reject(out_ret_value, out_resolve, out_reject);
364371
return mp_const_none;
365372
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Test raising an exception in async Python code running in runPythonAsync,
2+
// that the JavaScript-level promise is rejected with a PythonError.
3+
4+
const mp = await (await import(process.argv[2])).loadMicroPython();
5+
6+
try {
7+
await mp.runPythonAsync("await fail");
8+
} catch (error) {
9+
console.log(error.name, error.type);
10+
console.log(error.message);
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
PythonError NameError
2+
Traceback (most recent call last):
3+
File "<stdin>", line 1, in <module>
4+
NameError: name 'fail' isn't defined
5+

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy