diff --git a/docs/library/uasyncio.rst b/docs/library/uasyncio.rst index c0d0e85d71..641fa33457 100644 --- a/docs/library/uasyncio.rst +++ b/docs/library/uasyncio.rst @@ -266,3 +266,22 @@ Event Loop .. method:: Loop.close() Close the event loop. + +.. method:: Loop.set_exception_handler(handler) + + Set the exception handler to call when a Task raises an exception that is not + caught. The *handler* should accept two arguments: ``(loop, context)``. + +.. method:: Loop.get_exception_handler() + + Get the current exception handler. Returns the handler, or ``None`` if no + custom handler is set. + +.. method:: Loop.default_exception_handler(context) + + The default exception handler that is called. + +.. method:: Loop.call_exception_handler(context) + + Call the current exception handler. The argument *context* is passed through and + is a dictionary containing keys: ``'message'``, ``'exception'``, ``'future'``. diff --git a/tests/extmod/uasyncio_set_exception_handler.py b/tests/extmod/uasyncio_set_exception_handler.py new file mode 100644 index 0000000000..ad62a79b7b --- /dev/null +++ b/tests/extmod/uasyncio_set_exception_handler.py @@ -0,0 +1,46 @@ +# Test that tasks return their value correctly to the caller + +try: + import uasyncio as asyncio +except ImportError: + try: + import asyncio + except ImportError: + print("SKIP") + raise SystemExit + + +def custom_handler(loop, context): + print("custom_handler", repr(context["exception"])) + + +async def task(i): + # Raise with 2 args so exception prints the same in uPy and CPython + raise ValueError(i, i + 1) + + +async def main(): + loop = asyncio.get_event_loop() + + # Check default exception handler, should be None + print(loop.get_exception_handler()) + + # Set exception handler and test it was set + loop.set_exception_handler(custom_handler) + print(loop.get_exception_handler() == custom_handler) + + # Create a task that raises and uses the custom exception handler + asyncio.create_task(task(0)) + print("sleep") + 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") + await asyncio.sleep(0) + + print("done") + + +asyncio.run(main()) diff --git a/tests/extmod/uasyncio_set_exception_handler.py.exp b/tests/extmod/uasyncio_set_exception_handler.py.exp new file mode 100644 index 0000000000..4744641e54 --- /dev/null +++ b/tests/extmod/uasyncio_set_exception_handler.py.exp @@ -0,0 +1,8 @@ +None +True +sleep +custom_handler ValueError(0, 1) +sleep +custom_handler ValueError(1, 2) +custom_handler ValueError(2, 3) +done