aboutsummaryrefslogtreecommitdiff
path: root/tests/extmod
diff options
context:
space:
mode:
authorDamien George2020-11-30 17:38:19 +1100
committerDamien George2020-12-02 12:07:06 +1100
commitca40eb0fdadd5a963b9a065999b092f029a598d5 (patch)
tree0e7ba3c032406463a16ab237fb78910c6cdd94c9 /tests/extmod
parenta14ca31e8579a07f263bca0dd4b0dd03f43befa2 (diff)
extmod/uasyncio: Delay calling Loop.call_exception_handler by 1 loop.
When a tasks raises an exception which is uncaught, and no other task await's on that task, then an error message is printed (or a user function called) via a call to Loop.call_exception_handler. In CPython this call is made when the Task object is freed (eg via reference counting) because it's at that point that it is known that the exception that was raised will never be handled. MicroPython does not have reference counting and the current behaviour is to deal with uncaught exceptions as early as possible, ie as soon as they terminate the task. But this can be undesirable because in certain cases a task can start and raise an exception immediately (before any await is executed in that task's coro) and before any other task gets a chance to await on it to catch the exception. This commit changes the behaviour so that tasks which end due to an uncaught exception are scheduled one more time for execution, and if they are not await'ed on by the next scheduling loop, then the exception handler is called (eg the exception is printed out). Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'tests/extmod')
-rw-r--r--tests/extmod/uasyncio_set_exception_handler.py12
-rw-r--r--tests/extmod/uasyncio_set_exception_handler.py.exp1
2 files changed, 12 insertions, 1 deletions
diff --git a/tests/extmod/uasyncio_set_exception_handler.py b/tests/extmod/uasyncio_set_exception_handler.py
index ad62a79b7..fe7b83eb4 100644
--- a/tests/extmod/uasyncio_set_exception_handler.py
+++ b/tests/extmod/uasyncio_set_exception_handler.py
@@ -32,13 +32,23 @@ async def main():
# Create a task that raises and uses the custom exception handler
asyncio.create_task(task(0))
print("sleep")
- await asyncio.sleep(0)
+ for _ in range(2):
+ await asyncio.sleep(0)
# Create 2 tasks to test order of printing exception
asyncio.create_task(task(1))
asyncio.create_task(task(2))
print("sleep")
+ for _ in range(2):
+ await asyncio.sleep(0)
+
+ # Create a task, let it run, then await it (no exception should be printed)
+ t = asyncio.create_task(task(3))
await asyncio.sleep(0)
+ try:
+ await t
+ except ValueError as er:
+ print(repr(er))
print("done")
diff --git a/tests/extmod/uasyncio_set_exception_handler.py.exp b/tests/extmod/uasyncio_set_exception_handler.py.exp
index 4744641e5..fb4711469 100644
--- a/tests/extmod/uasyncio_set_exception_handler.py.exp
+++ b/tests/extmod/uasyncio_set_exception_handler.py.exp
@@ -5,4 +5,5 @@ custom_handler ValueError(0, 1)
sleep
custom_handler ValueError(1, 2)
custom_handler ValueError(2, 3)
+ValueError(3, 4)
done