Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Conversation

ndelangen
Copy link
Member

@ndelangen ndelangen commented Sep 18, 2025

What I did

Implemented a fix suggested by @yannbf for reporting errors even if they happen before storybook loads.

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

No manual testing required

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 canary-release-pr.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • Bug Fixes
    • Reduced noisy error reports by ignoring benign “React is running in production mode” messages.
    • Corrected error filtering to avoid sending skipped errors to telemetry.
    • Improved reliability of error reporting by queuing telemetry when the channel is unavailable and flushing when it returns.
    • Enhanced capture of unexpected errors by routing global errors and unhandled promise rejections into telemetry.
    • Overall stability improvements to error collection and reporting flow.

…l is unavailable. Update `shouldSkipError` to include additional error messages for better filtering.
Copy link
Contributor

coderabbitai bot commented Sep 18, 2025

Walkthrough

Implements telemetry error queuing and global error routing: adds queued error storage, flushes queued errors when a channel becomes available, reverses skip logic to early-return on skippable errors, and wires window-level error and unhandledrejection events to the telemetry sender. Updates the skip list to ignore a specific React devtools production-mode message.

Changes

Cohort / File(s) Summary
Telemetry error routing and queuing
code/core/src/manager/globals-runtime.ts
Adds a global error queue, prepares errors once, queues when no channel, flushes and emits when channel exists, reverses skip predicate to early-return, and registers global listeners for 'error' and 'unhandledrejection' to route into telemetry.
Telemetry skip list update
code/core/src/manager/utils/prepareForTelemetry.ts
Extends shouldSkipError to include the message "React is running in production mode" (noted as from react-dev-tools extension). No API changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant App
  participant GlobalHandlers as Global Error Handlers
  participant Telemetry as sendTelemetryError
  participant Channel as Telemetry Channel

  rect rgb(245,248,255)
  note over App,GlobalHandlers: New: Global routing
  User->>App: Causes runtime error / rejection
  App-->>GlobalHandlers: window "error" / "unhandledrejection"
  GlobalHandlers->>Telemetry: sendTelemetryError(error)
  end

  alt shouldSkipError(error) == true
    Telemetry-->>Telemetry: Return early (no emit)
  else Channel unavailable
    Telemetry->>Telemetry: preparedError = prepareForTelemetry(error)
    Telemetry->>Telemetry: queuedErrors.push(preparedError)
    Telemetry-->>GlobalHandlers: Return
  else Channel available
    Telemetry->>Channel: Flush queuedErrors (TELEMETRY_ERROR x N)
    Telemetry->>Channel: Emit TELEMETRY_ERROR(preparedError)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I thump my paws at bugs that fly,
Queue them neatly, stack them high;
When channels open, off they go—
A carrot-gram of status flow.
React’s whisper? Skip that thrill.
Onward, telemetry—hop until
The garden logs are calm and still. 🥕🐇

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately summarizes the primary changes: adding a queue for telemetry error reporting and filtering a browser-extension error message; it is concise, focused, and directly related to the changes in globals-runtime.ts and prepareForTelemetry.ts.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch norbert/queue-telemetry-manager-runtime

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

@ndelangen ndelangen self-assigned this Sep 18, 2025
@ndelangen ndelangen added bug patch:yes Bugfix & documentation PR that need to be picked to main branch telemetry ci:normal labels Sep 18, 2025
@ndelangen ndelangen requested review from shilman and yannbf September 18, 2025 10:22
Copy link
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: 0

🧹 Nitpick comments (6)
code/core/src/manager/utils/prepareForTelemetry.ts (2)

28-33: Make skip matching robust (substring + case-insensitive).

React/DevTools messages often vary slightly. Use a case-insensitive substring match so variants are also filtered.

Apply this diff:

-export const shouldSkipError = (error: Error) => errorMessages.includes(error?.message);
+export const shouldSkipError = (error: Error) => {
+  const msg = error?.message?.toLowerCase?.();
+  return !!msg && errorMessages.some((m) => msg.includes(m.toLowerCase()));
+};

32-32: Optional: accept unknown and normalize to a message.

This makes the filter resilient to strings/objects passed from unhandledrejection.

Example (outside the changed hunk):

export const shouldSkipError = (err: unknown) => {
  const msg =
    err instanceof Error
      ? err.message
      : typeof err === 'string'
      ? err
      : typeof (err as any)?.message === 'string'
      ? (err as any).message
      : '';
  const lower = msg.toLowerCase();
  return lower && errorMessages.some((m) => lower.includes(m.toLowerCase()));
};
code/core/src/manager/globals-runtime.ts (4)

13-14: Bound the queue to prevent unbounded memory growth.

If the channel is unavailable for a while, the queue can grow without limit.

Apply this diff:

-const queuedErrors: Error[] = [];
+const queuedErrors: Error[] = [];
+const MAX_QUEUED_ERRORS = 200; // drop oldest beyond this

15-22: Normalize input to Error before filtering and preparing.

Unhandled rejections can be strings/objects. Normalize first so skip logic and preparation are reliable.

Apply this diff:

-globalThis.sendTelemetryError = (error) => {
-  if (shouldSkipError(error)) {
+globalThis.sendTelemetryError = (raw) => {
+  const error =
+    raw instanceof Error
+      ? raw
+      : new Error(String((raw as any)?.message ?? raw));
+  if (shouldSkipError(error)) {
     return;
   }
 
-  const channel = globalThis.__STORYBOOK_ADDONS_CHANNEL__;
-  const preparedError = prepareForTelemetry(error);
+  const channel = globalThis.__STORYBOOK_ADDONS_CHANNEL__;
+  const preparedError = prepareForTelemetry(error);

23-26: Drop oldest when queue is full.

Prevents runaway memory while preserving the most recent context.

Apply this diff:

-  if (!channel) {
-    queuedErrors.push(preparedError);
+  if (!channel) {
+    if (queuedErrors.length >= MAX_QUEUED_ERRORS) queuedErrors.shift();
+    queuedErrors.push(preparedError);
     return;
   }

28-33: Flush without O(n) shift and guard against emit failures.

Use splice to drain in one shot and try/catch so one bad emit doesn’t stop the rest.

Apply this diff:

-  // Flush any queued errors first
-  while (queuedErrors.length > 0) {
-    const queuedError = queuedErrors.shift();
-    channel.emit(TELEMETRY_ERROR, queuedError);
-  }
+  // Flush any queued errors first
+  const toFlush = queuedErrors.splice(0, queuedErrors.length);
+  for (const queuedError of toFlush) {
+    try {
+      channel.emit(TELEMETRY_ERROR, queuedError);
+    } catch {
+      // swallow to avoid cascading failures
+    }
+  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 97f2089 and d399876.

📒 Files selected for processing (2)
  • code/core/src/manager/globals-runtime.ts (1 hunks)
  • code/core/src/manager/utils/prepareForTelemetry.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
code/core/src/manager/globals-runtime.ts (1)
code/core/src/manager/utils/prepareForTelemetry.ts (2)
  • shouldSkipError (32-32)
  • prepareForTelemetry (34-64)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: normal
  • GitHub Check: Danger JS
  • GitHub Check: Core Unit Tests, windows-latest
🔇 Additional comments (3)
code/core/src/manager/utils/prepareForTelemetry.ts (1)

28-30: Good call filtering React DevTools noise.

This avoids a common false-positive from the extension.

code/core/src/manager/globals-runtime.ts (2)

34-35: LGTM: emit current error after flush.

Order is correct; no reordering risk.


38-45: Global routing looks good; relies on normalization above.

Once normalization lands, both listeners will produce consistent telemetry.

Please manually verify:

  • With no addons channel, trigger 3+ errors and confirm queue size caps at MAX_QUEUED_ERRORS.
  • After channel becomes available, confirm queued errors flush followed by the current one, and no duplicates are left in the queue.

Copy link

nx-cloud bot commented Sep 18, 2025

View your CI Pipeline Execution ↗ for commit d399876

Command Status Duration Result
nx run-many -t build --parallel=3 ✅ Succeeded 48s View ↗

☁️ Nx Cloud last updated this comment at 2025-09-18 10:45:15 UTC

@ndelangen ndelangen merged commit 6b967f1 into next Sep 18, 2025
62 of 65 checks passed
@ndelangen ndelangen deleted the norbert/queue-telemetry-manager-runtime branch September 18, 2025 10:46
ndelangen added a commit that referenced this pull request Sep 18, 2025
…nager-runtime

Telemetry: Queue error reporting & filter browser-extention
(cherry picked from commit 6b967f1)
@github-actions github-actions bot added the patch:done Patch/release PRs already cherry-picked to main/release branch label Sep 18, 2025
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 telemetry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.