Skip to content

fix(init): surface wizard exit code and command stderr in Sentry events (CLI-1JA)#980

Merged
betegon merged 3 commits into
mainfrom
fix/init-wizard-exit-code-observability
May 19, 2026
Merged

fix(init): surface wizard exit code and command stderr in Sentry events (CLI-1JA)#980
betegon merged 3 commits into
mainfrom
fix/init-wizard-exit-code-observability

Conversation

@betegon

@betegon betegon commented May 19, 2026

Copy link
Copy Markdown
Member

Summary

Every event in CLI-1JA was identical in Sentry: `WizardError: Workflow returned an error` with no way to distinguish exit 11 (no files found), 20 (unknown platform), 30 (install failed), or 41 (codemod failed). The server already tags `wizard.exit_code` via `bailWithTracking`, but the CLI-side event never reflected it.

Changes

`wizard-runner.ts` — `handleFinalResult` now tags `wizard.exit_code` with the numeric workflow code when present, and uses `result.result?.message ?? result.error` as the `WizardError` message instead of the generic fallback. Priority order matches `formatError` (which already showed the right message in the terminal, just not in Sentry).

`run-commands.ts` — adds an explicit `addBreadcrumb` with up to 500 chars of stderr when a spawned command exits non-zero. The automatic Sentry child-process breadcrumb only captured the exit code; pnpm/npm/xcodebuild failure reasons were invisible.

Test Plan

  • New events in CLI-1JA should carry `wizard.exit_code: 11/20/30/41` so failures are immediately distinguishable
  • The exception message will be the actual bail reason (e.g. "Dependency installation failed after 5 attempts…") instead of "Workflow returned an error"
  • Command failure breadcrumbs will show the first 500 chars of stderr from pnpm/npm/xcodebuild

8 new unit tests cover both changes (`wizard-runner-handle-final-result.mocked.test.ts`, `run-commands.mocked.test.ts`).

Fixes CLI-1JA

betegon and others added 3 commits May 19, 2026 15:25
…ntry events

Tag wizard.exit_code on CLI-side Sentry events so each failure in CLI-1JA
is distinguishable (exit 11 = no files, 20 = unknown platform, 30 = install
failed, 41 = codemod failed). Use the actual bail message from the workflow
result instead of the generic "Workflow returned an error" fallback.

Add an explicit Sentry breadcrumb in run-commands when a command exits
non-zero, capturing the first 500 chars of stderr. This surfaces pnpm/npm/
xcodebuild failure reasons that were previously invisible in Sentry events.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ailures

formatError already uses result.error ?? inner?.message when showing the
terminal output. The WizardError throw now matches that priority so the
Sentry exception message captures the actual failure text for status:"failed"
results that carry result.error but no result.result.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Use !== undefined instead of != null for workflowCode guard (noEqualsToNull)
- Replace () => {} / () => undefined stubs with () => null in test helpers
  (resolves noEmptyBlockStatements + noUselessUndefined conflict)
- Biome auto-fixed import ordering and formatting in test files

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://cli.sentry.dev/_preview/pr-980/

Built to branch gh-pages at 2026-05-19 13:26 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions

Copy link
Copy Markdown
Contributor

Codecov Results 📊

6994 passed | Total: 6994 | Pass Rate: 100% | Execution Time: 0ms

📊 Comparison with Base Branch

Metric Change
Total Tests 📈 +8
Passed Tests 📈 +8
Failed Tests
Skipped Tests

All tests are passing successfully.

✅ Patch coverage is 100.00%. Project has 14201 uncovered lines.
❌ Project coverage is 77.05%. Comparing base (base) to head (head).

Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
- Coverage    77.09%    77.05%    -0.04%
==========================================
  Files          320       320         —
  Lines        61811     61867       +56
  Branches         0         0         —
==========================================
+ Hits         47646     47666       +20
- Misses       14165     14201       +36
- Partials         0         0         —

Generated by Codecov Action

@betegon betegon marked this pull request as ready for review May 19, 2026 13:27
@betegon betegon enabled auto-merge (squash) May 19, 2026 13:29

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c12823e. Configure here.

Comment thread src/lib/init/wizard-runner.ts
Comment thread src/lib/init/tools/run-commands.ts
@betegon betegon merged commit df7b32d into main May 19, 2026
28 checks passed
@betegon betegon deleted the fix/init-wizard-exit-code-observability branch May 19, 2026 13:31
Comment on lines +871 to +873
throw new WizardError(
result.result?.message ?? result.error ?? "Workflow returned an error",
{ exitCode }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: The error message priority in handleFinalResult is the reverse of formatError, causing potential mismatches between terminal and Sentry errors.
Severity: LOW

Suggested Fix

Align the error message prioritization in handleFinalResult with the logic in formatError. Change the expression in wizard-runner.ts to prioritize result.error first, for example: result.error ?? result.result?.message ?? "Workflow returned an error". This will ensure consistency between terminal output and Sentry reports.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/lib/init/wizard-runner.ts#L871-L873

Potential issue: The error message priority in `handleFinalResult` is reversed compared
to `formatError`. `handleFinalResult` uses `result.result?.message ?? result.error`,
while `formatError` uses `result.error ?? inner?.message`. If a `WorkflowRunResult`
object has both `result.error` and `result.result.message` set, the error message
displayed in the terminal will differ from the one sent to Sentry. This contradicts the
stated goal of the pull request, which is to make these two outputs match.

Did we get this right? 👍 / 👎 to inform future reviews.

betegon added a commit that referenced this pull request May 19, 2026
…981)

## Summary

The squash merge for #980 captured the first 3 commits but missed the
priority-order fix that came in as a follow-up from a bot review. Main
currently has `result.result?.message ?? result.error` but `formatError`
(which writes to the terminal) uses the opposite: `result.error ??
inner?.message`. This makes the terminal output and the Sentry exception
message inconsistent when both fields are set.

## Changes

One-line fix in `handleFinalResult` (`wizard-runner.ts`): swap the
operands so the Sentry message uses `result.error ??
result.result?.message`, matching `formatError` exactly.

In practice the two fields are mutually exclusive (structured bails
populate `result.result.message`; Mastra framework failures populate
`result.error`), so there's no user-visible behaviour change — just
consistency between what the terminal shows and what Sentry captures.

## Test Plan

Existing tests in `wizard-runner-handle-final-result.mocked.test.ts`
cover both the `result.error` and `result.result.message` paths and pass
unchanged.

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
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