fix(channels): demote channel-message 404s to typed error (OPENHUMAN-TAURI-2Y)#1732
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughIntroduces ChangesProvider-side message deletion handling
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
When a user deletes their telegram/discord/slack message provider-side, follow-up PATCH/DELETE/POST against the same id returns 404. The existing authed_json path funnels every non-transient non_2xx into report_error, which means OPENHUMAN-TAURI-2Y has accumulated ~454 events for a state that is fundamentally a UI-recovery cue, not a backend bug. Add a typed BackendApiError::MessageNotFound variant carrying the provider segment + message id parsed from the URL, and short-circuit the non_2xx branch when status == 404 AND the path matches /channels/<provider>/messages/<id>. The path matcher is intentionally narrow (exact 4-segment shape + literal 'channels' / 'messages' anchors) so 404s on any other route — auth probes, integration endpoints, mis-routed proxies — keep their Sentry signal. The drop is emitted as tracing::info at the call site so triage sweeps stay grep-visible without crossing the report_error threshold. Refs OPENHUMAN-TAURI-2Y. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…eNotFound recovery)
Four call sites in channels::bus consume the new
BackendApiError::MessageNotFound and recover in-flow instead of
counting it against MAX_EDIT_FAILURES or surfacing a generic warning:
flush_streaming_edit — clear state.message_id, latch
state.edit_disabled, return early so
subsequent dirty-buffer ticks fall back
to atomic delivery
flush_thinking_message — clear state.thinking_message_id, latch
state.thinking_edit_disabled (cloned
borrow so the mutation is allowed)
delete_channel_message — demote the warn! to info! since 'message
already gone' is a no-op success, not a
cleanup failure
finalize_channel_reply — skip the orphan-draft delete (there's
nothing to delete) and go straight to the
fresh atomic send so the user still sees
the canonical reply
Each branch keeps the existing non-404 error path intact, so genuine
backend failures retain their warn! signal.
Refs OPENHUMAN-TAURI-2Y.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…through
Two integration tests via the existing axum test scaffolding:
authed_json_surfaces_message_not_found_on_404 — POST to both
/channels/telegram/messages/1103 (Sentry shape) and
/channels/discord/messages/abc (proves provider-agnostic
parse_message_path)
authed_json_404_outside_messages_path_still_reports — GET on
/auth/profile returning 404 must NOT downcast to MessageNotFound
(guards against accidentally swallowing a real routing bug)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
02f9c97 to
28a024c
Compare
…TAURI-2Y) (tinyhumansai#1732) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Problem
Telegram (and Discord/Slack) users can delete a message on the provider side between the backend storing the relay row and our streaming loop issuing an edit. The follow-up PATCH/DELETE/POST then 404s on `/channels//messages/`. The current `authed_json` non-transient non_2xx path treats this as a backend bug and emits `report_error` for every event, producing `OPENHUMAN-TAURI-2Y` at ~454 events/wk. From a UX perspective the right answer is to clear the stale id and fall back to atomic delivery — not to surface a Sentry error.
Solution
Phase A scope from the original Jules plan (transient HTTP `is_transient_provider_http_failure` + before_send wiring) was dropped — `is_transient_provider_http_failure` / `is_transient_backend_api_failure` / `is_transient_integrations_failure` are already shipped in `src/core/observability.rs` + bilateral before_send in `src/main.rs` + `app/src-tauri/src/lib.rs`. Duplicating it would have collided with the existing classifier names.
Submission Checklist
Impact
Related
Summary by CodeRabbit