Skip to content

fix(cron): handle CancelledError so cancelled jobs report correct status#1894

Merged
xieyxclack merged 2 commits intoagentscope-ai:mainfrom
mvanhorn:osc/1829-fix-cron-cancelled-status
Mar 20, 2026
Merged

fix(cron): handle CancelledError so cancelled jobs report correct status#1894
xieyxclack merged 2 commits intoagentscope-ai:mainfrom
mvanhorn:osc/1829-fix-cron-cancelled-status

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

Summary

When a cron job's asyncio task is cancelled (shutdown, timeout, manual cancellation), asyncio.CancelledError is raised. Since Python 3.8, CancelledError inherits from BaseException - not Exception - so the existing except Exception blocks in the cron module silently miss it. The result: cancelled jobs report "running" (or a stale "success" from the prior run) instead of reflecting the cancellation.

Fix: Add explicit except asyncio.CancelledError handlers before every except Exception in:

  • CronManager._execute_once() - sets last_status = "cancelled" and re-raises
  • CronManager._heartbeat_callback() - logs and re-raises
  • CronExecutor.execute() - catches both TimeoutError and CancelledError, logs, and re-raises

Also adds "cancelled" to the CronJobState.last_status Literal type in models.py.

This follows the established pattern in app/runner/runner.py:274 and app/channels/dingtalk/channel.py:1559 which already handle CancelledError explicitly.

Changes

  • src/copaw/app/crons/manager.py: Add except asyncio.CancelledError in _execute_once() and _heartbeat_callback()
  • src/copaw/app/crons/executor.py: Add except asyncio.TimeoutError and except asyncio.CancelledError around wait_for() call
  • src/copaw/app/crons/models.py: Add "cancelled" to CronJobState.last_status Literal

Test plan

  • ruff check passes
  • Cancel a running cron task and verify last_status == "cancelled" instead of "success" or "running"
  • Timeout a cron job and verify the timeout is logged before the error propagates

Closes #1829

This contribution was developed with AI assistance (Claude Code + Codex).

asyncio.CancelledError inherits from BaseException (not Exception)
since Python 3.8, so `except Exception` blocks silently miss it.
This caused cancelled cron jobs to report "running" or stale "success"
status instead of reflecting the cancellation.

Add explicit `except asyncio.CancelledError` handlers before
`except Exception` in _execute_once(), _heartbeat_callback(), and
executor.execute(). Each handler sets the correct status, logs the
event, and re-raises so asyncio cancellation propagates correctly.

Also adds "cancelled" to the CronJobState.last_status Literal type.

Closes agentscope-ai#1829

This contribution was developed with AI assistance (Claude Code + Codex).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@xieyxclack xieyxclack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you for your contribution!

@xieyxclack xieyxclack merged commit e4786d4 into agentscope-ai:main Mar 20, 2026
36 checks passed
@mvanhorn
Copy link
Copy Markdown
Contributor Author

Thanks for the review and merge.

tudan110 pushed a commit to tudan110/QwenPaw that referenced this pull request Apr 4, 2026
…tus (agentscope-ai#1894)

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Cron job status incorrectly reports "success" when task is cancelled

2 participants