BUG-HUNT: [error-handling] async_cleanup.close_all swallows exceptions during resource cleanup #2571

Open
opened 2026-04-03 18:56:59 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/error-handling-async-cleanup-close-all-swallows-exceptions
  • Commit Message: fix(core): collect and re-raise exceptions from AsyncResourceTracker.close_all instead of swallowing them
  • Milestone: v3.7.0
  • Parent Epic: #1669

Bug Report: [error-handling] — async_cleanup.close_all swallows exceptions during resource cleanup

Severity Assessment

  • Impact: Failures during resource cleanup are silently ignored, which can lead to resource leaks or other unexpected behavior.
  • Likelihood: This is likely to happen if a resource's close() method raises an exception.
  • Priority: Medium

Location

  • File: src/cleveragents/core/async_cleanup.py
  • Function/Class: AsyncResourceTracker.close_all
  • Lines: 122-126

Description

The close_all method in AsyncResourceTracker catches all Exception and asyncio.CancelledError exceptions that occur when closing a resource. It logs the exception but does not re-raise it or otherwise signal to the caller that an error occurred. This can lead to silent failures and make it difficult to debug resource leaks or other issues related to resource cleanup.

This violates the project's fail-fast / no-error-suppression architectural principle (CONTRIBUTING.md §Error and Exception Handling): exceptions must only be caught when there is a meaningful recovery path, and must never be caught merely to be logged.

Evidence

# src/cleveragents/core/async_cleanup.py:122
            except (Exception, asyncio.CancelledError):
                logger.exception(
                    "Error closing async resource '%s'",
                    name,
                )

Expected Behavior

The close_all method should provide a way for the caller to know if any resources failed to close. This could be done by:

  • Re-raising the last exception after attempting to close all resources.
  • Returning a list of exceptions that occurred during cleanup.
  • Storing the exceptions in a field on the AsyncResourceTracker instance.

Actual Behavior

The close_all method catches and logs exceptions, but then continues as if no error occurred. The caller has no way of knowing that a resource failed to close.

Suggested Fix

Modify the close_all method to collect all exceptions that occur during cleanup and then re-raise a single exception (e.g., ExceptionGroup or a custom ResourceCleanupError) that contains information about all the failures.

Category

error-handling

Subtasks

  • Investigate AsyncResourceTracker.close_all in src/cleveragents/core/async_cleanup.py lines 122-126
  • Design the exception collection and re-raise strategy (e.g., ExceptionGroup, custom ResourceCleanupError, or return value)
  • Implement the fix: collect all exceptions during cleanup and surface them to the caller
  • Update or add unit tests (Behave/pytest) covering the case where one or more resources raise during close_all
  • Update or add integration tests (Robot) if applicable
  • Verify coverage >= 97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
  • All nox stages pass.
  • Coverage >= 97%.

Automated by CleverAgents Bot
Supervisor: Unknown | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/error-handling-async-cleanup-close-all-swallows-exceptions` - **Commit Message**: `fix(core): collect and re-raise exceptions from AsyncResourceTracker.close_all instead of swallowing them` - **Milestone**: v3.7.0 - **Parent Epic**: #1669 ## Bug Report: [error-handling] — `async_cleanup.close_all` swallows exceptions during resource cleanup ### Severity Assessment - **Impact**: Failures during resource cleanup are silently ignored, which can lead to resource leaks or other unexpected behavior. - **Likelihood**: This is likely to happen if a resource's `close()` method raises an exception. - **Priority**: Medium ### Location - **File**: `src/cleveragents/core/async_cleanup.py` - **Function/Class**: `AsyncResourceTracker.close_all` - **Lines**: 122-126 ### Description The `close_all` method in `AsyncResourceTracker` catches all `Exception` and `asyncio.CancelledError` exceptions that occur when closing a resource. It logs the exception but does not re-raise it or otherwise signal to the caller that an error occurred. This can lead to silent failures and make it difficult to debug resource leaks or other issues related to resource cleanup. This violates the project's **fail-fast / no-error-suppression** architectural principle (CONTRIBUTING.md §Error and Exception Handling): exceptions must only be caught when there is a meaningful recovery path, and must never be caught merely to be logged. ### Evidence ```python # src/cleveragents/core/async_cleanup.py:122 except (Exception, asyncio.CancelledError): logger.exception( "Error closing async resource '%s'", name, ) ``` ### Expected Behavior The `close_all` method should provide a way for the caller to know if any resources failed to close. This could be done by: - Re-raising the last exception after attempting to close all resources. - Returning a list of exceptions that occurred during cleanup. - Storing the exceptions in a field on the `AsyncResourceTracker` instance. ### Actual Behavior The `close_all` method catches and logs exceptions, but then continues as if no error occurred. The caller has no way of knowing that a resource failed to close. ### Suggested Fix Modify the `close_all` method to collect all exceptions that occur during cleanup and then re-raise a single exception (e.g., `ExceptionGroup` or a custom `ResourceCleanupError`) that contains information about all the failures. ### Category error-handling ## Subtasks - [ ] Investigate `AsyncResourceTracker.close_all` in `src/cleveragents/core/async_cleanup.py` lines 122-126 - [ ] Design the exception collection and re-raise strategy (e.g., `ExceptionGroup`, custom `ResourceCleanupError`, or return value) - [ ] Implement the fix: collect all exceptions during cleanup and surface them to the caller - [ ] Update or add unit tests (Behave/pytest) covering the case where one or more resources raise during `close_all` - [ ] Update or add integration tests (Robot) if applicable - [ ] Verify coverage >= 97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly. - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. - All nox stages pass. - Coverage >= 97%. --- **Automated by CleverAgents Bot** Supervisor: Unknown | Agent: ca-new-issue-creator
freemo added this to the v3.7.0 milestone 2026-04-03 18:57:19 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • MoSCoW: Should Have

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **MoSCoW**: Should Have --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#1669 Bug Hunting Session
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#2571
No description provided.