Skip to content

feat(react): Convert non-Error objects to Error instances in ErrorBoundary#1786

Draft
Copilot wants to merge 6 commits intomainfrom
copilot/assert-error-object-in-error-boundary
Draft

feat(react): Convert non-Error objects to Error instances in ErrorBoundary#1786
Copilot wants to merge 6 commits intomainfrom
copilot/assert-error-object-in-error-boundary

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Oct 15, 2025

  • Explore repository structure and understand ErrorBoundary implementation
  • Verify current behavior: non-Error objects (null, string, number, object) are NOT converted to Error instances
  • Update getDerivedStateFromError to convert non-Error objects to Error instances
  • Update componentDidCatch to convert non-Error objects for onError callback
  • Create convertToError helper function for consistent conversion logic
  • Add comprehensive tests to verify non-Error objects are properly converted in fallback props
  • Add tests to verify onError callback receives Error instances
  • Update type signatures to accept any type for error parameters (following Sentry's approach)
  • Add explanatory comments referencing Sentry's implementation
  • Run all tests to ensure no regressions (186 tests passed)
  • Run linter and type checker (no new errors)
Original prompt

This section details on the original issue you should resolve

<issue_title>[Feature]: If non error object thrown from children, ErrorBoundary should assert it as Error object in runtime</issue_title>
<issue_description>### Package Scope

@suspensive/react

Description

If non error object thrown from children, ErrorBoundary should assert it as Error object in runtime

Possible Solution

No response

etc.

No response</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #1785


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Oct 15, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
suspensive-next-streaming-react-query Error Error Mar 30, 2026 2:31pm
v2.suspensive.org Error Error Mar 30, 2026 2:31pm
v3.suspensive.org Error Error Mar 30, 2026 2:31pm
visualization.suspensive.org Error Error Mar 30, 2026 2:31pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Oct 15, 2025

⚠️ No Changeset found

Latest commit: 7f72a40

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@manudeli
Copy link
Copy Markdown
Member

@coauthors
Copy link
Copy Markdown

coauthors bot commented Oct 15, 2025

People can be co-author:

Candidate Reasons Count Add this as commit message
@Copilot #1786 (comment) #1786 2 Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
@manudeli #1786 (comment) #1786 (comment) 2 Co-authored-by: manudeli <61593290+manudeli@users.noreply.github.com>

Co-authored-by: manudeli <61593290+manudeli@users.noreply.github.com>
Co-authored-by: manudeli <61593290+manudeli@users.noreply.github.com>
Co-authored-by: manudeli <61593290+manudeli@users.noreply.github.com>
Co-authored-by: manudeli <61593290+manudeli@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Oct 15, 2025

@copilot ref: https://github.com/getsentry/sentry-javascript/blob/develop/packages/react/src/error.ts#L55-L71

Updated the implementation to follow Sentry's approach. Changed type signatures for getDerivedStateFromError and componentDidCatch to accept any type instead of Error, acknowledging that these methods can be invoked with non-error objects. Added comments referencing the Sentry implementation and GitHub issue #6167. (commit: short hash will be in next message)

@copilot ref: https://github.com/getsentry/sentry-javascript/blob/develop/packages/react/src/error.ts#L55-L71

Updated the implementation to follow Sentry's approach. Changed type signatures for getDerivedStateFromError and componentDidCatch to accept any type instead of Error, acknowledging that these methods can be invoked with non-error objects. Added comments referencing the Sentry implementation and GitHub issue #6167. (109a5c0)

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dummyjson.com
    • Triggering command: /usr/local/bin/node /home/REDACTED/work/suspensive/suspensive/node_modules/.pnpm/next@15.5.3_@babel&#43;core@7.28.4_react-dom@19.1.1_react@19.1.1__react@19.1.1/node_modules/next/dist/compiled/jest-worker/processChild.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@manudeli
Copy link
Copy Markdown
Member

@copilot rebase

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates @suspensive/react’s ErrorBoundary to normalize non-Error thrown values into real Error instances so fallback rendering and onError callbacks consistently receive an Error.

Changes:

  • Added a convertToError helper and applied it in getDerivedStateFromError and componentDidCatch.
  • Added tests covering conversion behavior for null, strings, numbers, and objects (both for fallback props and onError).
  • Updated an example tsconfig.tsbuildinfo file (TypeScript version metadata change).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
packages/react/src/ErrorBoundary.tsx Adds convertToError and normalizes error values passed through boundary lifecycles.
packages/react/src/ErrorBoundary.spec.tsx Adds test coverage ensuring fallback/onError receive Error instances for non-Error throws.
examples/vite-react-18-suspense-prerender-siblings-problem/tsconfig.tsbuildinfo Updates generated build-info metadata (TypeScript version).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +142 to 145
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static getDerivedStateFromError(error: any): ErrorBoundaryState {
return { isError: true, error: convertToError(error) }
}
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

getDerivedStateFromError is using any with an eslint disable. Since the method body immediately normalizes via convertToError, you can keep the React-typed signature (error: Error) or use unknown to avoid any and retain type-safety without suppressing the lint rule.

Copilot uses AI. Check for mistakes.
Comment on lines +157 to +158
// eslint-disable-next-line @typescript-eslint/no-explicit-any
componentDidCatch(error: any, info: ErrorInfo) {
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

componentDidCatch is also typed as any with a lint suppression. Consider using the standard React signature (error: Error) or unknown, and then normalize with convertToError, so callers of onError remain strongly typed and you can drop the eslint disable.

Suggested change
// eslint-disable-next-line @typescript-eslint/no-explicit-any
componentDidCatch(error: any, info: ErrorInfo) {
componentDidCatch(error: unknown, info: ErrorInfo) {

Copilot uses AI. Check for mistakes.
@@ -1 +1 @@
{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./vite.config.ts"],"version":"5.8.3"} No newline at end of file
{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./vite.config.ts"],"version":"5.9.2"} No newline at end of file
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

tsconfig.tsbuildinfo appears to be a generated build artifact, and this change is only updating the embedded TypeScript version (5.8.3 → 5.9.2) without any related source changes. It should typically be reverted/removed from the PR to avoid noisy diffs tied to local tooling versions.

Suggested change
{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./vite.config.ts"],"version":"5.9.2"}
{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./vite.config.ts"],"version":"5.8.3"}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 30, 2026

@copilot rebase

Rebased onto latest origin/main in commit 7f72a40. Also improved convertToError to use Object.prototype.toString checks (following Sentry's approach) so that transpiled Error subclasses with broken prototype chains (like ZodError in Zod v4) are correctly preserved as-is rather than being converted to plain Error instances.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: If non error object thrown from children, ErrorBoundary should assert it as Error object in runtime

3 participants