Skip to content

Commit f9e2d04

Browse files
Stop raising exception when actor is stopped.
BacgroundService raises BaseExceptionGroup. We can check if it was cancelled by checking if all exceptions on BaseGroupException are CancelledError. Signed-off-by: Elzbieta Kotulska <[email protected]>
1 parent 855a181 commit f9e2d04

File tree

3 files changed

+13
-7
lines changed

3 files changed

+13
-7
lines changed

RELEASE_NOTES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@
1717
## Bug Fixes
1818

1919
- Fixed bug with formulas raising exception when stopped.
20+
21+
- Fix a bug that raised `CancelledError` when actor was started with `frequenz.sdk.actor.run` and stopped.

src/frequenz/sdk/actor/_run_utils.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,22 @@ async def run(*actors: Actor) -> None:
3838
done_tasks, pending_tasks = await asyncio.wait(
3939
pending_tasks, return_when=asyncio.FIRST_COMPLETED
4040
)
41-
4241
# This should always be only one task, but we handle many for extra safety
4342
for task in done_tasks:
44-
# Cancellation needs to be checked first, otherwise the other methods
45-
# could raise a CancelledError
46-
if task.cancelled():
43+
# BackgroundService returns a BaseExceptionGroup containing multiple
44+
# exceptions. The 'await' statement raises these exceptions, and 'except*'
45+
# is used to handle them as a group. If the task raises multiple different
46+
# exceptions, 'except*' will be invoked multiple times, once for each
47+
# exception group.
48+
try:
49+
await task
50+
except* asyncio.CancelledError:
4751
_logger.info("Actor %s: Cancelled while running.", task.get_name())
48-
elif exception := task.exception():
52+
except* BaseException as err:
4953
_logger.error(
5054
"Actor %s: Raised an exception while running.",
5155
task.get_name(),
52-
exc_info=exception,
56+
exc_info=err,
5357
)
5458
else:
5559
_logger.info("Actor %s: Finished normally.", task.get_name())

tests/actor/test_actor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,6 @@ async def cancel_actor() -> None:
390390
(*RUN_INFO, "Actor EchoActor[EchoActor]: Starting..."),
391391
(*ACTOR_INFO, "Actor EchoActor[EchoActor]: Started."),
392392
(*ACTOR_INFO, "Actor EchoActor[EchoActor]: Cancelled."),
393-
(*RUN_ERROR, "Actor EchoActor[EchoActor]: Raised an exception while running."),
393+
(*RUN_INFO, "Actor EchoActor[EchoActor]: Cancelled while running."),
394394
(*RUN_INFO, "All 1 actor(s) finished."),
395395
]

0 commit comments

Comments
 (0)