Skip to content

No retry/backoff on Telegram 429 rate-limit errors for outbound notifications #67

Description

@Kingvic300

Summary

Outbound Telegram notifications have no retry/backoff for 429 rate-limit errors. A failed send is logged once and silently dropped — the bot's entire value is reliable delivery, and this gap directly undermines that.

Background

sendMessage/notifyChannel in src/telegram/client.ts:28-48 call bot.api.sendMessage() directly with no retry wrapper. grammy's own withRetries() helper (which handles 429 + retry_after backoff) is only applied internally to getMe() and webhook/polling setup — never to arbitrary bot.api.* calls like sendMessage (confirmed in node_modules/grammy/out/bot.js:477-520). The @grammyjs/auto-retry plugin is not a dependency (package.json).

A failed send (429, network blip) propagates up through @octokit/webhooks's handler-error path, is logged once by webhooks.onError (src/github/webhooks.ts), and the event is silently dropped — no retry, no alert.

Evidence: src/telegram/client.ts:35 (await bot.api.sendMessage(...) — no try/catch, no retry); node_modules/grammy/out/bot.js:477-520 (withRetries exists but is opt-in/internal-only); package.json (no @grammyjs/auto-retry).

Impact: this is an ops-notification bot — its entire value is reliable delivery. The active epic (#62) expanding configurable delivery across all event types is actively increasing notification volume and destinations, which increases exposure to Telegram's per-chat (~1 msg/sec) and global rate limits during bursts (bulk-closing issues, CI storms). Silent drops mean the team misses exactly the events (deploy failures, security alerts) the bot exists to surface.

Proposed Solution

Add @grammyjs/auto-retry as a transformer on bot.api, or wrap sendMessage/notifyChannel in a bounded retry loop that honors error.parameters.retry_after from grammy's GrammyError.

Technical Scope

  • src/telegram/client.tssendMessage, notifyChannel
  • package.json — new dependency (@grammyjs/auto-retry) if that route is chosen
  • Tests

Acceptance Criteria

  • A simulated 429 response with retry_after results in the message being retried and eventually delivered rather than dropped
  • A bounded retry ceiling prevents unbounded blocking on a persistently rate-limited chat
  • Existing successful send paths are unaffected

Edge Cases

  • 429 with no retry_after header/parameter present (fall back to a sane default backoff)
  • Persistent rate limiting exceeding the retry ceiling (must still surface a clear error/log, not fail silently)
  • Concurrent sends to multiple chats during the same burst

Risks

  • Low — additive change to the send path; the main risk is an unbounded retry loop blocking event processing, which the bounded-ceiling acceptance criterion is meant to prevent

Deliverables

  • Retry-wrapped (or transformer-wrapped) send path
  • Unit test mocking bot.api.sendMessage to throw a GrammyError with error_code: 429 and retry_after, asserting a retry occurs and eventually resolves

Priority

Medium — real reliability gap on the bot's core function, with increasing exposure as the active delivery-expansion epic (#62) ships.


GrantFox Evaluation

Impact Score: 68/100
Difficulty Score: 35/100
Priority Score: 58
Confidence: 85%

Category: Reliability

Estimated Reward Tier: B

AI Rationale: A concrete gap in the bot's single core function (reliable delivery), evidenced directly against the grammy library's actual retry-wrapping behavior, with increasing real-world exposure as an active feature epic expands notification volume. Well-scoped, low-risk fix.


Estimated Completion: 96 hours

Telegram: https://t.me/txioCommunity

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions