Skip to content

fix: stop spamming Sentry when draft publish/discard hits expected 4xx#5088

Draft
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/agent-d97bc61a
Draft

fix: stop spamming Sentry when draft publish/discard hits expected 4xx#5088
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/agent-d97bc61a

Conversation

@cursor
Copy link
Copy Markdown
Contributor

@cursor cursor Bot commented May 30, 2026

Summary

Fixes the Sentry alert: publish failed: 400 {"code":9,"message":"only draft versions can be published","details":[]} (#7516282874).

Root cause

The agent sidebar's DraftActionsWidget exposes Publish / Discard buttons for the latest draft. callApi unconditionally called console.error whenever the request returned a non-OK response:

if (response.ok) {
  onDismiss?.();
} else {
  const text = await response.text();
  console.error(`${action} failed:`, response.status, text);
}

The frontend Sentry SDK is initialized with captureConsoleIntegration({ levels: ["warn", "error"] }) (see web_src/src/sentry.ts), so this log is shipped as a Sentry event. But the case being hit here is a normal business-logic outcome — the draft was already published from another tab, the CLI, or by another collaborator — so the server correctly responds with 400 FailedPrecondition: only draft versions can be published. Treating that as an unhandled error pollutes Sentry and obscures real bugs.

Fix

In DraftActionsWidget:

  • Parse the API error body and surface message inline in the widget (role="alert").
  • For 4xx responses, treat them as expected outcomes — no console.error, no Sentry event.
  • When the 4xx message indicates the widget is stale (only draft versions can be published, version not found, version owner mismatch), call onDismiss so the bar disappears instead of leaving a dead Publish button.
  • Reserve console.error for genuine failures (5xx, network errors).

Tests

Added DraftActionsWidget.spec.tsx covering:

  • Silently dismisses (and does not call console.error) when the API returns the stale-draft 400.
  • Shows an inline error on other 4xx responses and stays mounted, without logging.
  • Still logs console.error (and surfaces inline) for 5xx responses so real failures keep flowing to Sentry.
  • Calls onDismiss after a successful publish.

All 4 new tests pass.

Open in Web Open in Cursor 

The agent sidebar's DraftActionsWidget unconditionally called
console.error whenever the publish/discard request returned a non-OK
response. The frontend Sentry SDK is configured with
captureConsoleIntegration({ levels: ['warn', 'error'] }), so a normal
business-logic outcome — most commonly a 400 'only draft versions can
be published' when the version was already published from another
tab/CLI — was being shipped to Sentry as a noisy error event.

Handle 4xx responses as expected outcomes: surface the server's
message inline (no console.error, no Sentry event) and silently
dismiss the widget when the response indicates the draft is stale
(version already published, missing, or owned by someone else).
Reserve console.error / Sentry for true failures (5xx and network
errors).
@superplanehq-integration
Copy link
Copy Markdown

👋 Commands for maintainers:

  • /sp start - Start an ephemeral machine (takes ~30s)
  • /sp stop - Stop a running machine (auto-executed on pr close)

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.

1 participant