Skip to content

notify/telegram: classify failure reasons from Telegram Bot API errors#5375

Open
softho0n wants to merge 2 commits into
prometheus:mainfrom
softho0n:telegram-failure-reasons
Open

notify/telegram: classify failure reasons from Telegram Bot API errors#5375
softho0n wants to merge 2 commits into
prometheus:mainfrom
softho0n:telegram-failure-reasons

Conversation

@softho0n

@softho0n softho0n commented Jul 6, 2026

Copy link
Copy Markdown

Pull Request Checklist

Which user-facing changes does this PR introduce?

[ENHANCEMENT] telegram: Classify failed notification metrics by failure reason. #3231

Summary

The telegram notifier returned client.Send() errors unclassified, so every failure was counted as reason="other" in alertmanager_notifications_failed_total.

Telegram goes through the telebot client, so there is no raw resp.StatusCode to classify at the transport level. Instead this classifies the structured errors telebot returns:

  • telebot.FloodError (429 with retry_after) → rateLimited
  • *telebot.Error (carries the Telegram error_code, which mirrors HTTP status) → notify.GetFailureReasonFromStatusCode
  • anything else is returned unchanged, keeping the default reason - no error-string parsing

Same approach as discord/webex (#5332). Retry behavior is unchanged (always retry=true on error, as before).

Tests

@softho0n softho0n requested a review from a team as a code owner July 6, 2026 11:10
@softho0n softho0n force-pushed the telegram-failure-reasons branch from 231702b to ab85926 Compare July 6, 2026 11:12
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0d4e869d-575e-4390-96e4-39093d669bb7

📥 Commits

Reviewing files that changed from the base of the PR and between a39291e and 39f37c7.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • notify/telegram/telegram.go
  • notify/telegram/telegram_test.go
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • notify/telegram/telegram_test.go
  • notify/telegram/telegram.go

📝 Walkthrough

Walkthrough

The Telegram notifier now wraps message-send errors using a new wrapWithFailureReason helper that classifies telebot.FloodError and *telebot.Error status codes into notify.Reason values. A table-driven test validates this classification, and the changelog documents the enhancement.

Changes

Telegram failure reason wrapping

Layer / File(s) Summary
Error classification helper and wiring
notify/telegram/telegram.go, CHANGELOG.md
Adds errors import, wraps the send error via new wrapWithFailureReason helper in Notify, which maps telebot.FloodError and *telebot.Error status codes to notify.Reason values, and adds a changelog entry.
Failure reason test coverage
notify/telegram/telegram_test.go
Adds a table-driven test using httptest to simulate Telegram error responses (401, 403, 400, 500, 429) and asserts the resulting notify.ErrorWithReason matches expected reasons.

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Notifier
  participant TelegramAPI
  participant wrapWithFailureReason

  Notifier->>TelegramAPI: Send message
  TelegramAPI-->>Notifier: error response
  Notifier->>wrapWithFailureReason: wrap(err)
  wrapWithFailureReason-->>Notifier: ErrorWithReason(reason)
Loading

Possibly related PRs

  • prometheus/alertmanager#5332: Introduces the underlying authError/rateLimited reason definitions and status-code mapping used by the Telegram notifier's new failure classification.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: classifying Telegram Bot API failure reasons.
Description check ✅ Passed The description follows the template well, includes checklist items, related issue, tests, and release notes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
notify/telegram/telegram_test.go (1)

217-290: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a fallback-path test case.

All cases exercise the FloodError/*telebot.Error branches; none cover the default path in wrapWithFailureReason where the error is returned unchanged (unstructured error). Adding one would close coverage on that branch.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@notify/telegram/telegram_test.go` around lines 217 - 290, Add a fallback-path
test to TestTelegramNotifyFailureReason that exercises the default branch in
wrapWithFailureReason, where a non-structured/unrecognized error is returned
unchanged. Use the existing Telegram notifier setup in New and Notify, but have
the test server return or trigger an error that is neither FloodError nor
*telebot.Error, then assert the returned error does not wrap a
notify.ErrorWithReason and is passed through as-is.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@notify/telegram/telegram_test.go`:
- Around line 217-290: Add a fallback-path test to
TestTelegramNotifyFailureReason that exercises the default branch in
wrapWithFailureReason, where a non-structured/unrecognized error is returned
unchanged. Use the existing Telegram notifier setup in New and Notify, but have
the test server return or trigger an error that is neither FloodError nor
*telebot.Error, then assert the returned error does not wrap a
notify.ErrorWithReason and is passed through as-is.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: eebe29b8-5a26-404d-a8f0-969662677ef2

📥 Commits

Reviewing files that changed from the base of the PR and between b8e6252 and ab85926.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • notify/telegram/telegram.go
  • notify/telegram/telegram_test.go

@softho0n softho0n force-pushed the telegram-failure-reasons branch 2 times, most recently from aab51c4 to a39291e Compare July 6, 2026 11:23
The telegram integration returned errors from the telebot client without
classification, so all failed notifications were counted under the
default reason in alertmanager_notifications_failed_total.

Classify structured telebot errors before returning them: flood-control
errors map to rateLimited, and API errors with a known description map
via their error code (401/403 to authError, 429 to rateLimited, other
4xx to clientError, 5xx to serverError). Errors that telebot does not
surface in a structured form are returned unchanged and keep the
default reason.

Part of prometheus#3231

Signed-off-by: Seunghun Shin <18shshin@gmail.com>
@softho0n softho0n force-pushed the telegram-failure-reasons branch from a39291e to 39f37c7 Compare July 6, 2026 11:26
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.

3 participants