Skip to content

fix(core): categorize UniversalStore internal errors#34597

Closed
MatviySuk wants to merge 2 commits into
storybookjs:nextfrom
RuBrock:clean-fix-universal-store-errors
Closed

fix(core): categorize UniversalStore internal errors#34597
MatviySuk wants to merge 2 commits into
storybookjs:nextfrom
RuBrock:clean-fix-universal-store-errors

Conversation

@MatviySuk
Copy link
Copy Markdown

@MatviySuk MatviySuk commented Apr 19, 2026

Closes #34566

What I did

Categorized internal UniversalStore failures by replacing generic TypeError occurrences with a granular UniversalStoreError hierarchy.

Currently, when a UniversalStore follower times out or is misused, it throws a plain TypeError. These are caught by prepareForTelemetry.ts and bucketed generically as
SB_MANAGER_UNCAUGHT_0001, making it impossible to distinguish store-specific failures from other uncaught manager errors in telemetry.

Specifically, I:

  • Defined an abstract UniversalStoreError and 5 specialized subclasses in the shared/universal-store layer.
  • Refactored UniversalStore to throw these specific errors with codes 1 and 1001 through 1004 (Timeout, NotConstructable, IdRequired, NotReady, MissingSubscribeArgument).
  • Registered the MANAGER_UNIVERSAL-STORE category in manager-errors.ts and re-exported the errors to completely avoid circular dependencies between the shared and manager
    bundles.
  • Updated all affected inline snapshots in index.test.ts.

Checklist for Contributors

Testing

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

  • unit tests

Manual testing

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

No manual testing is necessary.

This PR fixes a telemetry categorization bug where internal UniversalStore failures were being generically reported as uncaught manager errors. It does not alter any user-facing features, UI components, or public APIs.

Because manually reproducing these specific store initialization and timeout failures in a browser requires intentionally breaking core configurations, manual testing provides no practical diagnostic value. Instead, the updated index.test.ts suite exhaustively simulates these edge cases and verifies that the new error classes are thrown with the correct category, code, and fromStorybook flag required by the telemetry handler.

Documentation

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

(Note: No public documentation changes were required as this is an internal telemetry/error architecture improvement).

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

  • New Features
    • Improved universal store error handling: operations now surface clearer, categorized error messages for construction, missing/invalid id, pre-ready actions, subscription arguments, and follower timeouts.
  • Tests
    • Updated inline snapshots and tests to expect the new, standardized error messages and formats.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 19, 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: 56c1deed-7dd9-4219-ad92-287062034906

📥 Commits

Reviewing files that changed from the base of the PR and between ff1034e and 690e07f.

📒 Files selected for processing (2)
  • code/core/src/manager-errors.ts
  • code/core/src/shared/universal-store/errors.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • code/core/src/manager-errors.ts
  • code/core/src/shared/universal-store/errors.ts

📝 Walkthrough

Walkthrough

Adds a UniversalStore-specific error hierarchy and replaces previous generic TypeError throws with the new error classes; the errors are defined in a new module and re-exported via the manager-errors enum/category.

Changes

Cohort / File(s) Summary
Error Hierarchy Definition
code/core/src/shared/universal-store/errors.ts
Adds UniversalStoreError abstract base class and five concrete errors: UniversalStoreFollowerTimeoutError, UniversalStoreNotConstructableError, UniversalStoreIdRequiredError, UniversalStoreNotReadyError, UniversalStoreMissingSubscribeArgumentError, including codes, messages, and structured data where applicable.
Error Re-export and Category
code/core/src/manager-errors.ts
Adds MANAGER_UNIVERSAL_STORE = 'MANAGER_UNIVERSAL-STORE' to Category and re-exports the five UniversalStore error classes.
UniversalStore Implementation & Tests
code/core/src/shared/universal-store/index.ts, code/core/src/shared/universal-store/index.test.ts
Replaces thrown TypeErrors with the new specific error classes across construction, create/id validation, subscribe argument checks, readiness checks for setState/send, and follower timeout handling; updates inline test snapshots to match new error types/messages.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@code/core/src/manager-errors.ts`:
- Around line 51-57: The re-export of UniversalStoreFollowerTimeoutError,
UniversalStoreIdRequiredError, UniversalStoreMissingSubscribeArgumentError,
UniversalStoreNotConstructableError, and UniversalStoreNotReadyError currently
imports from a relative module without an explicit extension; update the export
source string './shared/universal-store/errors' to include the explicit
TypeScript extension (i.e., './shared/universal-store/errors.ts') so the
re-export uses the project's explicit-extension convention.

In `@code/core/src/shared/universal-store/errors.ts`:
- Line 1: The import of StorybookError should use an explicit .ts extension;
update the import statement that references StorybookError (symbol:
StorybookError) in errors.ts to import from './storybook-error.ts' instead of
'./storybook-error' so the relative TypeScript module import includes the
explicit file extension.
- Around line 42-48: The error message in UniversalStoreNotReadyError
(constructor in class UniversalStoreNotReadyError) references a nonexistent
readyPromise; update the message string to reference the correct readiness API
untilReady() and adjust any inline snapshot tests that contain the old message
so they assert the new text; ensure the message still includes the store id,
action, and guidance like "You can get the current status with store.status, or
await store.untilReady() to wait for the store to be ready before sending
events."
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 049ec030-44ca-48dd-b3d9-bb2950132f1e

📥 Commits

Reviewing files that changed from the base of the PR and between d226aa9 and ff1034e.

📒 Files selected for processing (4)
  • code/core/src/manager-errors.ts
  • code/core/src/shared/universal-store/errors.ts
  • code/core/src/shared/universal-store/index.test.ts
  • code/core/src/shared/universal-store/index.ts

Comment thread code/core/src/manager-errors.ts Outdated
Comment thread code/core/src/shared/universal-store/errors.ts Outdated
Comment thread code/core/src/shared/universal-store/errors.ts
@valentinpalkovic
Copy link
Copy Markdown
Contributor

Superseded by #34592

@github-project-automation github-project-automation Bot moved this from Empathy Queue (prioritized) to Done in Core Team Projects May 21, 2026
@valentinpalkovic valentinpalkovic self-assigned this May 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Categorize UniversalStore follower timeout error instead of generic UncaughtManagerError

2 participants