Skip to content

Commit c7bbd48

Browse files
betegonclaude
andcommitted
fix(init): tag wizard.outcome on all early-exit paths
Several paths exited without setting wizard.outcome, leaving runs with no outcome tag in Sentry and making the funnel gap unanalyzable: - ctrl+c during a spinner (InkUI.requestCancel) → "abandoned" - user said no at the welcome/confirm prompt (preamble) → "bailed" - user selected "No, exit" at the experimental warning → "bailed" - git status check bailed → "bailed" - resolveInitContext returned null → "bailed" The preamble paths flush cleanly (event loop drains, beforeExit fires) so their tags will reliably reach Sentry. The InkUI path calls process.exit(130) which skips beforeExit, but setting the tag before the setImmediate tick gives the SDK its best chance to flush. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
1 parent 6c6ea45 commit c7bbd48

2 files changed

Lines changed: 9 additions & 0 deletions

File tree

src/lib/init/ui/ink-ui.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
import { openSync } from "node:fs";
5050
import { ReadStream } from "node:tty";
51+
import { setTag } from "@sentry/node-core/light";
5152
import { CLI_VERSION } from "../../constants.js";
5253
import { stripAnsi } from "../../formatters/plain-detect.js";
5354
import { formatFeedbackHint, type InitFeedbackOutcome } from "../feedback.js";
@@ -817,12 +818,16 @@ export class InkUI implements WizardUI {
817818
if (this.cancelRequested) {
818819
// Safety valve: teardown already started but hasn't finished
819820
// (or something is stuck). Force-exit so the user isn't trapped.
821+
setTag("wizard.outcome", "abandoned");
820822
process.exit(130);
821823
}
822824
this.cancelRequested = true;
823825
this.failureMessage = "Setup cancelled.";
824826
this.feedback("cancelled");
825827
this.tearDown();
828+
// Mark as abandoned before exit so the Sentry span carries the
829+
// outcome even though beforeExit never fires for explicit process.exit().
830+
setTag("wizard.outcome", "abandoned");
826831
// Match the SIGINT convention so shells (and CI) see a
827832
// distinguishable exit. The runner's `await using` won't get a
828833
// chance to run after this, but tearDown above already did all

src/lib/init/wizard-runner.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ async function preamble(
396396
} catch (err) {
397397
if (err instanceof WizardCancelledError) {
398398
captureException(err);
399+
setTag("wizard.outcome", "bailed");
399400
showCancelledFeedback(ui);
400401
process.exitCode = 0;
401402
return false;
@@ -409,6 +410,7 @@ async function preamble(
409410
throw err;
410411
}
411412
if (!confirmed) {
413+
setTag("wizard.outcome", "bailed");
412414
showCancelledFeedback(ui);
413415
process.exitCode = 0;
414416
return false;
@@ -424,6 +426,7 @@ async function preamble(
424426
ui,
425427
});
426428
if (!gitOk) {
429+
setTag("wizard.outcome", "bailed");
427430
showCancelledFeedback(ui);
428431
process.exitCode = 0;
429432
return false;
@@ -608,6 +611,7 @@ export async function runWizard(initialOptions: WizardOptions): Promise<void> {
608611
: initialOptions;
609612
const context = await resolveInitContext(effectiveOptions, ui);
610613
if (!context) {
614+
setTag("wizard.outcome", "bailed");
611615
return;
612616
}
613617

0 commit comments

Comments
 (0)