Skip to content

Commit 797f8f6

Browse files
committed
Python: Improve exception handling for the coroutine passed to slint.run_event_loop()
If an exception is thrown, propagate it. Otherwise it becomes difficult to debug... cc #4137
1 parent a29c22a commit 797f8f6

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

api/python/slint/README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,6 @@ For the common use case of interacting with REST APIs, we recommend the [`aiohtt
339339
### Known Limitations
340340

341341
- Pipes and sub-processes are only supported on Unix-like platforms.
342-
- Exceptions thrown in the coroutine passed to `slint.run_event_loop()` don't cause the loop to terminate. This behaviour may
343-
change in a future release.
344342

345343
## Third-Party Licenses
346344

api/python/slint/slint/__init__.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,10 +464,20 @@ async def main_receiver(image_model: slint.ListModel) -> None:
464464
async def run_inner() -> None:
465465
global quit_event
466466
loop = typing.cast(SlintEventLoop, asyncio.get_event_loop())
467+
468+
tasks: typing.List[asyncio.Task[typing.Any]] = [
469+
asyncio.ensure_future(quit_event.wait(), loop=loop)
470+
]
471+
472+
main_task = None
467473
if main_coro:
468-
loop.create_task(main_coro)
474+
main_task = loop.create_task(main_coro)
475+
tasks.append(main_task)
476+
477+
done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
469478

470-
await quit_event.wait()
479+
if main_task is not None and main_task in done:
480+
main_task.result() # propagate exception if thrown
471481

472482
global quit_event
473483
quit_event = asyncio.Event()

api/python/slint/tests/test_async.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,11 @@ async def launch_process(exception_check: typing.List[Exception]) -> None:
207207
slint.run_event_loop(launch_process(exception_check))
208208
if len(exception_check) > 0:
209209
raise exception_check[0]
210+
211+
212+
def test_exception_thrown() -> None:
213+
async def throws() -> None:
214+
raise RuntimeError("Boo")
215+
216+
with pytest.raises(RuntimeError, match="Boo"):
217+
slint.run_event_loop(throws())

0 commit comments

Comments
 (0)