Skip to content

fix: harden album buffer error paths - #169

Merged
QueryPlanner merged 1 commit into
mainfrom
fix/album-buffer-error-paths
Aug 19, 2026
Merged

fix: harden album buffer error paths#169
QueryPlanner merged 1 commit into
mainfrom
fix/album-buffer-error-paths

Conversation

@QueryPlanner

Copy link
Copy Markdown
Owner

What

Hardens four latent robustness gaps in the Telegram photo-album buffering state machine (telegram/album_buffer.py and telegram/bot.py), found during a code-reduction audit and tracked as separate items in #163.

Why

None of the four gaps caused an observed failure, but two were "safe by accident": correct only because of how the code happens to be called or scheduled today, not because anything enforces it. A future refactor could silently reintroduce a stuck asyncio.Future (a hung Telegram turn) or a double-processed album. Fixing all four together keeps the album-buffer state machine self-consistent in one small, reviewable change rather than four disconnected diffs against the same file.

How

  • _handle_album_turn now resolves album.future in its own finally block, so every validation early-return (too many photos, missing photo, oversized photo/album) is covered even if the method is ever called outside _process_flushed_album.
  • AlbumBuffer.add_message now rolls back the self._buffers entry if asyncio.create_task for the max-wait watchdog raises, so a failed schedule can't leave an album with no timer able to flush it.
  • The previously swallowed exception in _safe_handle_update (album-wait path) is now logged at warning instead of debug, with a comment explaining why it must not re-raise (the album turn already reports its own user-facing error).
  • AlbumBuffer._flush now documents the synchronous, no-await invariant that keeps the debounce/max-wait race safe, so a future change that adds an await before album.processed = True doesn't silently reintroduce a double-flush.

Tests

  • New test: _handle_album_turn resolves a pending album.future on a validation early-return, called directly (not via _process_flushed_album)
  • New test: a create_task failure during add_message does not leave the album orphaned in self._buffers
  • New test: the suppressed album-wait exception is logged at warning level
  • New test: calling _flush twice back-to-back (simulating the debounce/max-wait race) flushes exactly once
  • pytest tests/test_telegram_album_buffer.py tests/test_telegram_bot.py -q passes (245 passed)
  • ruff check, ruff format --check pass with no new warnings
  • mypy src/blacki/telegram/ passes with no new warnings

Related Issues

Closes #163

- Resolve album.future inside _handle_album_turn itself, not only
  via the caller's finally block
- Roll back the buffer entry if scheduling the max-wait watchdog
  task raises during add_message
- Log the suppressed album-wait exception at warning, not debug
- Document the sync invariant that keeps debounce/max-wait flush
  race-free

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@QueryPlanner
QueryPlanner merged commit 6258278 into main Aug 19, 2026
3 checks passed
@QueryPlanner
QueryPlanner deleted the fix/album-buffer-error-paths branch August 19, 2026 09:07
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.

Album buffering: future/buffer leaks on error paths

1 participant