Skip to content

CLI: Prompt for init crash reports#34316

Merged
JReinhold merged 3 commits into
nextfrom
jeppe/fix-error-reports-on-init
Mar 27, 2026
Merged

CLI: Prompt for init crash reports#34316
JReinhold merged 3 commits into
nextfrom
jeppe/fix-error-reports-on-init

Conversation

@JReinhold
Copy link
Copy Markdown
Contributor

@JReinhold JReinhold commented Mar 25, 2026

Closes #

What I did

Prompt for crash report consent when storybook init fails, so init errors can include full stack traces after the user opts in. This reuses the existing consent/cache flow and adds coverage for both accept and reject paths.

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Crash report prompting
  1. Run a sandbox for template, e.g. yarn task --task sandbox --start-from auto --template react-vite/default-ts
  2. Open Storybook in your browser
  3. Access X story

-->

  1. From the repo root, compile create-storybook with yarn nx compile create-storybook.
  2. In a separate terminal, start the local telemetry collector with cd scripts && yarn jiti ./event-log-collector.ts.
  3. Create a fresh temp project and trigger an init failure:
    tmp="$(mktemp -d)" && cd "$tmp" && printf '{ "name": "sb-init-repro", "private": true }\n' > package.json && HOME="$tmp/.home" env -u STORYBOOK_DISABLE_TELEMETRY STORYBOOK_TELEMETRY_URL="http://127.0.0.1:6007/event-log" STORYBOOK_TELEMETRY_DEBUG=1 node PATH_TO_STORYBOOK_REPO/storybook/code/lib/create-storybook/dist/bin/index.js --no-dev
  4. Confirm init fails with project detection and now shows the crash report consent prompt.
  5. Accept the prompt once, then inspect events with curl -s http://127.0.0.1:6007/event-log | python -m json.tool and verify the error event includes payload.error.
  6. Repeat with a fresh temp directory/Home and reject the prompt; verify the error event is still sent but payload.error is omitted.
Not prompting in non-blocking error cases
  1. Build the local create-storybook CLI from the Storybook repo:
cd /Users/jeppe/dev/work/storybook/storybook
yarn nx compile create-storybook
  1. Start the local telemetry event collector in a separate terminal:
cd /Users/jeppe/dev/work/storybook/storybook/scripts
yarn jiti ./event-log-collector.ts
  1. Create a fresh Vite React TypeScript app:
npm create vite@latest sb-nonblocking-repro -- --template react-ts
cd sb-nonblocking-repro
npm install
  1. Replace vite.config.ts with this file:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig(() => ({
  plugins: [react()],
}));
  1. Run storybook init with the locally built CLI and point telemetry at the event collector:
env -u STORYBOOK_DISABLE_TELEMETRY \
STORYBOOK_TELEMETRY_URL="http://127.0.0.1:6007/event-log" \
STORYBOOK_TELEMETRY_DEBUG=1 \
node PATH_TO_YOUR_STORYBOOK_REPO/storybook/code/lib/create-storybook/dist/bin/index.js \
  --features test \
  --yes \
  --no-dev

Expected result

  • storybook init continues far enough to hit addon-vitest setup
  • addon-vitest setup fails non-fatally
  • no crash-report consent prompt appears

Inspect the captured telemetry

curl -s http://127.0.0.1:6007/event-log | python -m json.tool

Look for an error event with:

  • "eventType": "init"
  • "blocking": false
  • no payload.error field unless crash-report consent was already cached beforehand

If needed, I can also write the matching blocking init error verification steps in the same format.

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • Tests

    • Expanded telemetry tests: improved TTY handling, covered init failure paths, prompt/consent flows, cached-consent and non-blocking init scenarios; added assertions for consent persistence and telemetry payloads.
  • Bug Fixes

    • Init events now respect cached crash-report consent, include full error details only when consented, and suppress prompts for non-blocking init events.

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Mar 25, 2026

View your CI Pipeline Execution ↗ for commit 82b7f69

Command Status Duration Result
nx run-many -t compile,check,knip,test,lint,fmt... ✅ Succeeded 7m 8s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-27 09:04:29 UTC

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Mar 25, 2026

View your CI Pipeline Execution ↗ for commit 5a63119


☁️ Nx Cloud last updated this comment at 2026-03-25 11:13:51 UTC

@JReinhold JReinhold added the patch:yes Bugfix & documentation PR that need to be picked to main branch label Mar 25, 2026
@JReinhold JReinhold marked this pull request as ready for review March 25, 2026 11:15
@JReinhold JReinhold requested a review from shilman March 25, 2026 11:16
@JReinhold JReinhold self-assigned this Mar 25, 2026
eventType?: EventType;
};

const promptCrashReports = async () => {
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.

Are we making sure that we don't prompt if the error is a non-blocking error? blocking: false. Or do we even want to prompt in this scenario?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good catch @valentinpalkovic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Why would we not prompt in a non-blocking scenario? Don't we still benefit from the information?

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.

We could prompt with a slightly different message to avoid confusion, e.g. "Some errors happened, though Storybook successfully installed. "

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've disabled prompting for errors in non-blocking scenarios, specifically during init only. I've also updated the manual QA steps in the PR description with this case.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 74565f6d-7a66-4106-9088-127053632deb

📥 Commits

Reviewing files that changed from the base of the PR and between 7808856 and 82b7f69.

📒 Files selected for processing (1)
  • code/core/src/core-server/withTelemetry.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • code/core/src/core-server/withTelemetry.test.ts

📝 Walkthrough

Walkthrough

Adds an optional eventType to telemetry options and changes telemetry error-level and prompt logic so 'init' events defer the immediate 'error' fallback, allowing preset/cache/prompt-driven crash-report consent; tests expanded to cover TTY, prompt, cache, and non-blocking init flows.

Changes

Cohort / File(s) Summary
Telemetry core
code/core/src/core-server/withTelemetry.ts
Added TelemetryOptions.eventType?: EventType; getErrorLevel treats eventType === 'init' specially (doesn't immediately fallback to 'error' and instead consults preset/cache/prompt); sendTelemetryError passes eventType to getErrorLevel and forces skipPrompt = true for non-blocking init errors (when blocking === false).
Telemetry tests
code/core/src/core-server/withTelemetry.test.ts
Extended Vitest setup to save/restore process.stdout.isTTY; added tests covering withTelemetry and sendTelemetryError for 'init' flows including TTY/non-CI conditions, prompt accept/reject behavior and cache writes, non-blocking init telemetry (no prompt, blocking:false), and cached consent behavior; adjusted getErrorLevel tests to exercise init-specific branches.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant withTelemetry
    participant sendTelemetryError
    participant getErrorLevel
    participant Cache
    participant Prompt

    Caller->>withTelemetry: invoke (error, eventType='init')
    withTelemetry->>sendTelemetryError: report error (passes eventType)
    sendTelemetryError->>getErrorLevel: determine level (passes eventType, blocking, skipPrompt)
    alt presetOptions present
        getErrorLevel-->>sendTelemetryError: return preset-determined level
    else presetOptions missing & eventType='init'
        getErrorLevel->>Cache: read 'enableCrashReports'
        alt cache has consent
            Cache-->>getErrorLevel: consent value
            getErrorLevel-->>sendTelemetryError: return level (full or error)
        else no cache
            alt skipPrompt true
                getErrorLevel-->>sendTelemetryError: return non-prompted level (e.g., error)
            else
                getErrorLevel->>Prompt: prompt.confirm for consent
                Prompt-->>getErrorLevel: accept/reject
                getErrorLevel->>Cache: cache.set('enableCrashReports', value)
                Cache-->>getErrorLevel: cached
                getErrorLevel-->>sendTelemetryError: return level (full or error)
            end
        end
    end
    sendTelemetryError-->>withTelemetry: level & payload (blocking/immediate flags)
    withTelemetry-->>Caller: continue execution
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 26, 2026

Fails
🚫 The "#### Manual testing" section must be filled in. Please describe how to test the changes you've made, step by step, so that reviewers can confirm your PR works as intended.

Generated by 🚫 dangerJS against 82b7f69

@storybook-app-bot
Copy link
Copy Markdown

storybook-app-bot Bot commented Mar 26, 2026

Package Benchmarks

Commit: 82b7f69, ran on 27 March 2026 at 09:07:55 UTC

The following packages have significant changes to their size or dependencies:

storybook

Before After Difference
Dependency count 50 50 0
Self size 20.47 MB 20.46 MB 🎉 -11 KB 🎉
Dependency size 16.55 MB 16.55 MB 0 B
Bundle Size Analyzer Link Link

@storybook/nextjs-vite

Before After Difference
Dependency count 92 92 0
Self size 1.12 MB 1.12 MB 0 B
Dependency size 22.76 MB 22.73 MB 🎉 -33 KB 🎉
Bundle Size Analyzer Link Link

@storybook/react-native-web-vite

Before After Difference
Dependency count 121 121 0
Self size 30 KB 30 KB 0 B
Dependency size 23.83 MB 23.80 MB 🎉 -32 KB 🎉
Bundle Size Analyzer Link Link

@storybook/react-vite

Before After Difference
Dependency count 82 82 0
Self size 35 KB 35 KB 0 B
Dependency size 20.55 MB 20.51 MB 🎉 -33 KB 🎉
Bundle Size Analyzer Link Link

@storybook/cli

Before After Difference
Dependency count 184 184 0
Self size 782 KB 780 KB 🎉 -1 KB 🎉
Dependency size 67.69 MB 67.68 MB 🎉 -11 KB 🎉
Bundle Size Analyzer Link Link

@storybook/codemod

Before After Difference
Dependency count 177 177 0
Self size 32 KB 32 KB 0 B
Dependency size 66.22 MB 66.21 MB 🎉 -11 KB 🎉
Bundle Size Analyzer Link Link

create-storybook

Before After Difference
Dependency count 51 51 0
Self size 1.04 MB 1.04 MB 🎉 -779 B 🎉
Dependency size 37.03 MB 37.02 MB 🎉 -11 KB 🎉
Bundle Size Analyzer node node

@JReinhold JReinhold merged commit 8d12309 into next Mar 27, 2026
122 of 125 checks passed
@JReinhold JReinhold deleted the jeppe/fix-error-reports-on-init branch March 27, 2026 09:34
@github-actions github-actions Bot mentioned this pull request Mar 31, 2026
19 tasks
valentinpalkovic pushed a commit that referenced this pull request Apr 2, 2026
…-init

CLI: Prompt for init crash reports
(cherry picked from commit 8d12309)
@github-actions github-actions Bot mentioned this pull request Apr 2, 2026
19 tasks
@github-actions github-actions Bot added the patch:done Patch/release PRs already cherry-picked to main/release branch label Apr 2, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Apr 30, 2026
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug ci:normal patch:done Patch/release PRs already cherry-picked to main/release branch patch:yes Bugfix & documentation PR that need to be picked to main branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants