From 20987932b7725d2b3da7a40f41c49697f4ecbc95 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Thu, 19 Dec 2024 10:36:47 +0100 Subject: [PATCH] Forward exceptions from thread executor --- .../chip/testing/matter_testing.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py index c9eeafb905cbd4..964764f35299e9 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py @@ -18,6 +18,7 @@ import argparse import asyncio import builtins +import contextlib import inspect import json import logging @@ -101,11 +102,24 @@ class TestRunnerHooks: def asyncio_thread_executor(f): + """Run an async function in an event loop in a separate thread. + + This decorator function blocks the current thread until the async function + completes. Also, it forwards any exceptions that occurred in that thread. + """ @wraps(f) def wrapper(*args, **kwargs): - thread = threading.Thread(target=asyncio.run, args=(f(*args, **kwargs),)) + def run(coroutine, q: queue.Queue): + try: + asyncio.run(coroutine) + except Exception as e: + q.put(e) + q = queue.Queue() + thread = threading.Thread(target=run, args=(f(*args, **kwargs), q)) thread.start() thread.join() + with contextlib.suppress(queue.Empty): + raise q.get(block=False) return wrapper