mirror of
https://github.com/micropython/micropython.git
synced 2026-01-05 03:30:14 +01:00
webassembly/asyncio: Fix ThenableEvent to handle rejected thenables.
Prior to this fix, if a JavaScript thenable/Promise that was part of an asyncio chain was rejected it would be ignored because the Python-side `ThenableEvent` did not register a handler for the rejection. That's fixed by this commit, and a corresponding test added. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -79,9 +79,8 @@ class TopLevelCoro:
|
||||
|
||||
class ThenableEvent:
|
||||
def __init__(self, thenable):
|
||||
self.result = None # Result of the thenable
|
||||
self.waiting = None # Task waiting on completion of this thenable
|
||||
thenable.then(self.set)
|
||||
thenable.then(self.set, self.cancel)
|
||||
|
||||
def set(self, value=None):
|
||||
# Thenable/Promise is fulfilled, set result and schedule any waiting task.
|
||||
@@ -90,6 +89,15 @@ class ThenableEvent:
|
||||
_task_queue.push(self.waiting)
|
||||
self.waiting = None
|
||||
|
||||
def cancel(self, value=None):
|
||||
# Thenable/Promise is rejected, set error and schedule any waiting task.
|
||||
self.error = jsffi.JsException(
|
||||
value, getattr(value, "name", None), getattr(value, "message", None)
|
||||
)
|
||||
if self.waiting:
|
||||
_task_queue.push(self.waiting)
|
||||
self.waiting = None
|
||||
|
||||
def remove(self, task):
|
||||
self.waiting = None
|
||||
|
||||
@@ -101,7 +109,9 @@ class ThenableEvent:
|
||||
cur_task.data = self
|
||||
# Wait for the thenable to fulfill.
|
||||
yield
|
||||
# Return the result of the thenable.
|
||||
# Raise the error, or return the result, of the thenable.
|
||||
if hasattr(self, "error"):
|
||||
raise self.error
|
||||
return self.result
|
||||
|
||||
|
||||
|
||||
@@ -117,6 +117,10 @@ async def main():
|
||||
|
||||
# Test top-level waiting on a coro that catches.
|
||||
await main()
|
||||
|
||||
# Test top-level waiting on a task that catches.
|
||||
t = asyncio.create_task(main())
|
||||
await t
|
||||
`);
|
||||
|
||||
console.log("finished");
|
||||
|
||||
@@ -22,4 +22,6 @@ jsFail
|
||||
caught exception: <class 'JsException'> <class 'JsProxy'> ('Error', 'jsFail')
|
||||
jsFail
|
||||
caught exception: <class 'JsException'> <class 'JsProxy'> ('Error', 'jsFail')
|
||||
jsFail
|
||||
caught exception: <class 'JsException'> <class 'JsProxy'> ('Error', 'jsFail')
|
||||
finished
|
||||
|
||||
Reference in New Issue
Block a user