summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/webassembly/asyncio/core.py3
-rw-r--r--ports/webassembly/objjsproxy.c3
-rw-r--r--tests/ports/webassembly/asyncio_top_level_await.mjs32
-rw-r--r--tests/ports/webassembly/asyncio_top_level_await.mjs.exp6
4 files changed, 41 insertions, 3 deletions
diff --git a/ports/webassembly/asyncio/core.py b/ports/webassembly/asyncio/core.py
index 47846fc25..1d0124a6a 100644
--- a/ports/webassembly/asyncio/core.py
+++ b/ports/webassembly/asyncio/core.py
@@ -243,8 +243,7 @@ def get_event_loop():
def current_task():
- if cur_task is None:
- raise RuntimeError("no running event loop")
+ assert cur_task is not None
return cur_task
diff --git a/ports/webassembly/objjsproxy.c b/ports/webassembly/objjsproxy.c
index 2d46702ff..93c40d835 100644
--- a/ports/webassembly/objjsproxy.c
+++ b/ports/webassembly/objjsproxy.c
@@ -566,7 +566,8 @@ static mp_obj_t jsproxy_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
// decouples the task from the thenable and allows cancelling the task.
if (mp_asyncio_context != MP_OBJ_NULL) {
mp_obj_t cur_task = mp_obj_dict_get(mp_asyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
- if (cur_task != mp_const_none) {
+ mp_obj_t top_level_task = mp_obj_dict_get(mp_asyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR__top_level_task));
+ if (cur_task != top_level_task) {
mp_obj_t thenable_event_class = mp_obj_dict_get(mp_asyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_ThenableEvent));
mp_obj_t thenable_event = mp_call_function_1(thenable_event_class, self_in);
mp_obj_t dest[2];
diff --git a/tests/ports/webassembly/asyncio_top_level_await.mjs b/tests/ports/webassembly/asyncio_top_level_await.mjs
index 234b7a6ce..449985b49 100644
--- a/tests/ports/webassembly/asyncio_top_level_await.mjs
+++ b/tests/ports/webassembly/asyncio_top_level_await.mjs
@@ -88,3 +88,35 @@ print("top-level end")
`);
console.log("finished");
+
+/**********************************************************/
+// Top-level await's on a JavaScript function that throws.
+
+console.log("= TEST 4 ==========");
+
+globalThis.jsFail = async () => {
+ console.log("jsFail");
+ throw new Error("jsFail");
+};
+
+await mp.runPythonAsync(`
+import asyncio
+import js
+
+# Test top-level catching from a failed JS await.
+try:
+ await js.jsFail()
+except Exception as er:
+ print("caught exception:", type(er), type(er.args[0]), er.args[1:])
+
+async def main():
+ try:
+ await js.jsFail()
+ except Exception as er:
+ print("caught exception:", type(er), type(er.args[0]), er.args[1:])
+
+# Test top-level waiting on a coro that catches.
+await main()
+`);
+
+console.log("finished");
diff --git a/tests/ports/webassembly/asyncio_top_level_await.mjs.exp b/tests/ports/webassembly/asyncio_top_level_await.mjs.exp
index 66fefd2dc..90c817f3d 100644
--- a/tests/ports/webassembly/asyncio_top_level_await.mjs.exp
+++ b/tests/ports/webassembly/asyncio_top_level_await.mjs.exp
@@ -17,3 +17,9 @@ top-level wait task
task end
top-level end
finished
+= TEST 4 ==========
+jsFail
+caught exception: <class 'JsException'> <class 'JsProxy'> ('Error', 'jsFail')
+jsFail
+caught exception: <class 'JsException'> <class 'JsProxy'> ('Error', 'jsFail')
+finished