refactor(init): route wizard errors through framework error pipeline#678
refactor(init): route wizard errors through framework error pipeline#678
Conversation
Replace direct `process.exitCode = 1` in wizard-runner.ts with thrown WizardError instances so errors flow through Stricli's error handler, gaining Sentry telemetry capture and consistent formatting. WizardError carries a `rendered` flag so clack-displayed errors are not duplicated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨
Bug Fixes 🐛Init
Other
Internal Changes 🔧Init
Other
Other
🤖 This preview updates automatically when you update the PR. |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f742575. Configure here.
The server validates DSN and URL fields with z.string().url(). The previous placeholders "(dry-run)" failed Zod validation, breaking dry-run after the create-sentry-project step. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This reverts commit dfe1666.
Tests now expect runWizard to throw WizardError instead of setting process.exitCode directly. Added a 10s timeout on the describe block to prevent CI from hanging indefinitely if a test accidentally waits for interactive input. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a WizardError thrown inside the wizard loop was caught by the outer catch block, it would call log.error + cancel again before re-wrapping. Now WizardError instances are re-thrown immediately to avoid duplicate output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Results 📊✅ 134 passed | Total: 134 | Pass Rate: 100% | Execution Time: 0ms 📊 Comparison with Base Branch
✨ No test changes detected All tests are passing successfully. ✅ Patch coverage is 100.00%. Project has 1423 uncovered lines. Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 95.56% 95.57% +0.01%
==========================================
Files 222 222 —
Lines 32111 32120 +9
Branches 0 0 —
==========================================
+ Hits 30686 30697 +11
- Misses 1425 1423 -2
- Partials 0 0 —Generated by Codecov Action |
| `Create one at ${terminalLink(teamsUrl)} and run sentry init again.` | ||
| ); | ||
| cancel("Setup failed."); | ||
| process.exitCode = 1; | ||
| return null; | ||
| throw new WizardError("No teams in your organization."); | ||
| } | ||
| } else if (teams.length === 1) { | ||
| opts = { ...opts, team: (teams[0] as SentryTeam).slug }; |
There was a problem hiding this comment.
Bug: An outer try...catch block in resolvePreSpinnerOptions swallows a WizardError from a failed team creation, causing the wizard to continue with incomplete configuration.
Severity: HIGH
Suggested Fix
The outer catch block should re-throw the WizardError to ensure the wizard process is properly halted upon team resolution failure. This can be done by checking if (err instanceof WizardError) { throw err; } within the outer catch block.
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#L524-L530
Potential issue: In the `resolvePreSpinnerOptions` function, if an organization has no
teams, the wizard attempts to auto-create one. If this creation fails, a `WizardError`
is thrown. However, this error is caught by an outer `try...catch` block that does not
re-throw it. As a result, the function returns the `opts` object without the required
`team` property. The wizard then proceeds with this incomplete configuration,
potentially causing downstream failures or silent misconfiguration, despite logging an
error to the user. This behavior is a regression from the previous implementation which
would have halted execution.

Summary
WizardErrorclass extendingCliErrorwith arenderedflag — tells the framework error handler to skip re-displaying errors that clack already showedprocess.exitCode = 1locations inwizard-runner.tswiththrow new WizardError(...)Sentry.captureException, consistent exit code handling, future error improvements apply automaticallyexitCode = 0) are unchangedTest plan
sentry initin a project → cancel at experimental warning → exits 0 (unchanged)sentry initwith no network → shows error, exits 1 (now via framework)echo '' | sentry init→ shows TTY error, exits 1 (now viaWizardError({ rendered: false }))cancel()+ framework error message)🤖 Generated with Claude Code