Skip to content

fix: resolve Sentry issue 526#2815

Merged
M3gA-Mind merged 1 commit into
tinyhumansai:mainfrom
CodeGhost21:fix/sentry-tauri-rust-cd-updater-endpoint-non-success
May 28, 2026
Merged

fix: resolve Sentry issue 526#2815
M3gA-Mind merged 1 commit into
tinyhumansai:mainfrom
CodeGhost21:fix/sentry-tauri-rust-cd-updater-endpoint-non-success

Conversation

@CodeGhost21
Copy link
Copy Markdown
Contributor

Summary

  • Add tauri-plugin-updater's status-blind non-success log line ("update endpoint did not respond with a successful status code") to UPDATER_TRANSIENT_MESSAGE_PHRASES in src/core/observability.rs so the before_send updater filter (is_updater_transient_event) drops it instead of letting it reach Sentry as an error.
  • Targets self-hosted Sentry TAURI-RUST-CD (https://sentry.tinyhumans.ai/organizations/tinyhumans/issues/526/) — ~151 events over 9 days, all Windows, logger=log, no domain/status tag, first seen openhuman@0.54.0.
  • Same message-fast-path mechanism the filter already documents for "Tauri's updater plugin can also emit message-only events".

Problem

tauri-plugin-updater (v2.10.1, updater.rs) logs, on any non-2xx response to the update-manifest probe:

} else {
    log::error!("update endpoint did not respond with a successful status code");
}

This is the dependency's own internal log::error! — it is emitted regardless of what our updater.check() callers (app/src-tauri/src/lib.rs) do with the returned Result, and the status code is discarded. Sentry's log integration captures it as an error event with the bare message, logger=log, and no domain or status tag.

The existing updater filter (is_updater_transient_event) drops updater noise two ways: (1) a domain-agnostic message fast-path (UPDATER_TRANSIENT_MESSAGE_PHRASES), and (2) a domain=update* + transient-status/transport check. This event has no domain tag, so only the message fast-path can catch it — and the phrase wasn't listed. Result: ~151 unactionable Sentry events (background update checks failing intermittently behind GitHub rate-limits / CDN hiccups on Windows).

Solution

Add the literal plugin string to the message fast-path list:

const UPDATER_TRANSIENT_MESSAGE_PHRASES: &[&str] = &[
    "failed to check for updates: error sending request",
    "github api error: 403",
    "github api error: 5",
    "error sending request for url (https://github.com/tinyhumansai/openhuman/releases/",
    "update endpoint did not respond with a successful status code",   // ← new (TAURI-RUST-CD)
];

The phrase is highly distinctive (it literally names "update endpoint"), so matching it domain-agnostically via the existing fast-path is safe — it cannot collide with non-updater logs. The matching doc-comment is extended to explain why this shape is message-only and status-blind.

Trade-off (status-blind): the plugin discarded the status, so the event carries no actionable detail (no status, no URL, no version) — even if the underlying status were a 404, this particular event is not a useful signal. A genuinely-broken update manifest still surfaces with full structured context through the core's domain=update check_releases path, which preserves the status and keeps non-transient statuses visible (UPDATER_TRANSIENT_HTTP_STATUSES deliberately omits 404). So no real signal is lost by dropping this redundant message-only line.

This is the "skip is correct" bucket per the repo's Sentry-triage convention: the failure originates inside a third-party dependency's internal logging (we cannot demote it at the call site), it is non-actionable background noise, and the supervising code already handles a failed update check gracefully.

Files changed

  • src/core/observability.rs — new UPDATER_TRANSIENT_MESSAGE_PHRASES entry + doc-comment; 2 new tests.

Submission Checklist

If a section does not apply to this change, mark the item as N/A with a one-line reason. Do not delete items.

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy — 2 new tests:
    • updater_endpoint_non_success_message_is_dropped — happy path; asserts both is_updater_transient_message(...) and that the exact 526 shape (message-only event, no domain tag) is dropped by is_updater_transient_event.
    • updater_endpoint_non_success_anchor_does_not_silence_unrelated_errors — rejection contract over 4 actionable/unrelated messages (signature-verification failure, deserialize error, two non-updater "status code" mentions) so a future refactor that loosens the substring fails loudly. The existing updater_real_panic_still_reported guard remains green.
  • Diff coverage ≥ 80% — the single new array entry and the doc-comment are exercised by the new positive test; the negative test pins the boundary.
  • (N/A) Coverage matrix updated — observability before_send classifier change is behaviour-only inside core::observability; not a tracked feature row in docs/TEST-COVERAGE-MATRIX.md.
  • (N/A) All affected feature IDs from the matrix are listed under ## Related — no matrix feature IDs affected.
  • No new external network dependencies introduced — pure in-process classifier addition; lib unit tests only.
  • (N/A) Manual smoke checklist updated — observability filter; no user-visible UI surface, no release-cut behaviour change.
  • (N/A) Linked issue closed via Closes #NNN — Sentry-only fix; no GitHub issue. The Sentry-Issue trailer below carries the back-reference.

Impact

  • Runtime: Desktop (Tauri shell + core). before_send (wired in both the core and app/src-tauri/src/lib.rs:2098) now drops the plugin's status-blind non-success log line. No change to update behaviour, the retry/endpoint-iteration in the plugin, or the core's structured check_releases reporting.
  • Performance / noise: Net positive — removes the TAURI-RUST-CD event stream (~151 events / 9 days) from the tauri-rust project.
  • Security: None — no new code paths, no PII, no auth surface.
  • Migration / compatibility: None — additive entry in an existing phrase list.
  • Observability trade-off: a failing background update check now leaves only a log::debug!/warn breadcrumb locally instead of a Sentry error. The actionable signal (a real non-transient status) still flows through the core's structured domain=update path with the status attached.

Notes for reviewers

  • Risk level: low. Single additive, highly-distinctive phrase in an existing OR-list + tests; no behavioural change beyond dropping this one message-only event shape.
  • The phrase is the verbatim tauri-plugin-updater v2.10.1 updater.rs Display string. If the plugin is upgraded and the wording changes, the filter would stop matching — the positive test pins the current string so a drift is at least visible (the test would still pass, but CD would resurface in Sentry, signalling the need to re-sync).
  • Follow-up: none required.
  • Pre-push pnpm format runs cargo fmt --check; the change is Rust-only and cargo fmt --manifest-path Cargo.toml is clean. If the JS half of the hook can't run in the fresh worktree (no node_modules), the push uses --no-verify and that is the only reason.

Related

  • Sentry-Issue: TAURI-RUST-CD (https://sentry.tinyhumans.ai/organizations/tinyhumans/issues/526/)
  • Filter: is_updater_transient_event / UPDATER_TRANSIENT_MESSAGE_PHRASES / UPDATER_TRANSIENT_HTTP_STATUSES in src/core/observability.rs.
  • Emit site: tauri-plugin-updater updater.rs (internal log::error!); call sites in app/src-tauri/src/lib.rs (updater.check()).
  • Closes:
  • Follow-up PR(s)/TODOs: none.

Add tauri-plugin-updater's status-blind non-success log line ("update
endpoint did not respond with a successful status code") to
UPDATER_TRANSIENT_MESSAGE_PHRASES so the before_send updater filter drops
it instead of surfacing it as a Sentry error.

The plugin (updater.rs) logs this internally on any non-2xx response to the
update-manifest probe and discards the status code, so the captured event
has no domain/status tag and no actionable detail — it can only be matched
by the message string. It is distinctive to the updater ("update endpoint"),
so matching it domain-agnostically via the existing message fast-path is
safe. A genuinely-broken manifest still surfaces with full structured
context through the core's domain=update check_releases path (which keeps
non-transient statuses like 404 visible). Background update checks failing
intermittently behind GitHub rate-limits / CDN hiccups are unactionable
noise — same treatment as the adjacent GitHub 403 / 5xx phrases.

Sentry: TAURI-RUST-CD
https://sentry.tinyhumans.ai/organizations/tinyhumans/issues/526/
@CodeGhost21 CodeGhost21 requested a review from a team May 28, 2026 05:08
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Warning

Review limit reached

@CodeGhost21, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 14 minutes and 36 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 353450df-f24d-4603-8f58-7b5e268f6f1c

📥 Commits

Reviewing files that changed from the base of the PR and between 3f2e2f2 and 6e2658c.

📒 Files selected for processing (1)
  • src/core/observability.rs

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

@oxoxDev oxoxDev self-assigned this May 28, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

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

@CodeGhost21 hey! the code looks good to me — the fix is exactly right and well-reasoned. The phrase is distinctive enough that domain-agnostic matching is safe, the trade-off write-up is thorough, and the two tests (positive + rejection contract) cover the right boundaries. No concerns on my end.

There's a CI failure on "Build & smoke-test core image" that needs to be resolved first. Once that's green i'll come back and approve. Let me know if you need any help sorting it out.

@oxoxDev oxoxDev removed their assignment May 28, 2026
@oxoxDev oxoxDev self-requested a review May 28, 2026 18:08
Copy link
Copy Markdown
Contributor

@oxoxDev oxoxDev left a comment

Choose a reason for hiding this comment

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

Walkthrough

Adds one literal phrase ("update endpoint did not respond with a successful status code") to existing UPDATER_TRANSIENT_MESSAGE_PHRASES fast-path in src/core/observability.rs. Drops tauri-plugin-updater's status-blind non-success log (TAURI-RUST-CD, ~151 events / 9 days, Windows). +56/-0, 1 file. Adds positive + polarity tests. All CI green.

Verified

  • Phrase originates upstream in tauri-plugin-updater::updater.rs log::error!("update endpoint did not respond with a successful status code") — discards status code → Sentry event has no domain/status tag → only message fast-path can catch it ✓
  • New entry slots into the existing is_updater_transient_message substring scan; const is private to this matcher (no cross-leak) ✓
  • Polarity test pins rejection of signature-verification, deserialize, backend 500, tool-exit-code messages — phrase substring doesn't appear in any of those, so polarity is real and not just symbolic ✓
  • 404 stays NOT in UPDATER_TRANSIENT_HTTP_STATUSES per doc — genuinely-broken manifests still surface via domain=update check_releases

Nits

  • Worth a brief follow-up: the existing "github api error: 5" phrase is broader than the new entry (would match "github api error: 5xx legend says" or any 5-prefix). Out of scope here, but a separate cleanup PR to anchor "github api error: 50" / "github api error: 502" etc explicitly would tighten the surface. Don't block on it.

Questions

  • None. Tightly-scoped Sentry classifier addition, byte-identical to documented pattern.

@M3gA-Mind M3gA-Mind merged commit 9415fd1 into tinyhumansai:main May 28, 2026
35 of 37 checks passed
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.

4 participants