Conversation
…ror handling - Added `ErrorBoundary.Observer` component to capture errors from all nested `<ErrorBoundary/>` components. - Updated error handling to call both the Observer's `onError` and each ErrorBoundary's `onError` when an error occurs. - Enhanced documentation and examples for using `ErrorBoundary.Observer`. - Added tests to verify the functionality of the new Observer component and its interaction with nested ErrorBoundaries.
People can be co-author:
|
🦋 Changeset detectedLatest commit: fc912bf The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Size Change: +276 B (+0.46%) Total Size: 60.3 kB
ℹ️ View Unchanged
|
…h usage examples - Updated documentation for `ErrorBoundary.Observer` to clarify its purpose in observing errors from nested `<ErrorBoundary/>` components. - Added before-and-after code examples demonstrating the simplification of error handling with `ErrorBoundary.Observer`. - Improved explanations of the `onError` prop usage in the context of nested error boundaries.
ErrorBoundary.Observer
There was a problem hiding this comment.
Pull request overview
Adds a new ErrorBoundary.Observer component to @suspensive/react that lets consumers observe onError events from all nested <ErrorBoundary /> instances, primarily for centralized error reporting integrations (e.g., Sentry).
Changes:
- Add
ErrorBoundary.Observer(via a new internalErrorObserverContext) and wireErrorBoundary’sonErrorto also notify the observer chain. - Add unit tests covering observer invocation and bubbling order.
- Update English/Korean docs and add a changeset for a minor release.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react/src/ErrorBoundary.tsx | Implements ErrorBoundary.Observer and context-based bubbling of onError notifications. |
| packages/react/src/ErrorBoundary.spec.tsx | Adds test cases validating observer callbacks and call order. |
| docs/suspensive.org/src/content/ko/docs/react/ErrorBoundary.mdx | Documents ErrorBoundary.Observer, updates comparison table and Sentry migration guidance (KO). |
| docs/suspensive.org/src/content/en/docs/react/ErrorBoundary.mdx | Documents ErrorBoundary.Observer, updates comparison table and Sentry migration guidance (EN). |
| .changeset/early-hornets-relax.md | Declares a minor version bump for @suspensive/react for the new feature. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| * | ||
| * @example | ||
| * ```tsx | ||
| * import * as Sentry from '@sentry/react' |
There was a problem hiding this comment.
The JSDoc example uses ErrorBoundary.Observer/<ErrorBoundary/> but only imports @sentry/react. This snippet won’t type-check/run as written; it should also import ErrorBoundary from @suspensive/react (and/or adjust the example to be self-contained).
| * import * as Sentry from '@sentry/react' | |
| * import * as Sentry from '@sentry/react' | |
| * import { ErrorBoundary } from '@suspensive/react' |
| * A component that captures errors from all nested ErrorBoundary components. | ||
| * Both Observer's onError and each ErrorBoundary's own onError will be called when an error is caught. |
There was a problem hiding this comment.
The docstring says this component “captures” errors, but ErrorBoundary.Observer doesn’t catch/handle errors (it only observes callbacks from nested ErrorBoundarys). Consider rephrasing to avoid implying it behaves like an error boundary itself.
| * A component that captures errors from all nested ErrorBoundary components. | |
| * Both Observer's onError and each ErrorBoundary's own onError will be called when an error is caught. | |
| * A component that observes errors reported by all nested ErrorBoundary components. | |
| * It does not catch errors itself, but its onError callback is invoked whenever a nested ErrorBoundary catches an error, | |
| * in addition to that ErrorBoundary's own onError handler. |
| Observer: ({ onError, children }: PropsWithChildren<{ onError: (error: Error, info: ErrorInfo) => void }>) => { | ||
| const parent = useContext(ErrorObserverContext) | ||
| const handleError = useCallback( |
There was a problem hiding this comment.
This introduces a new public API surface (ErrorBoundary.Observer), but there are no corresponding type-level tests in ErrorBoundary.test-d.tsx (the repo already uses .test-d.tsx for public typings). Adding a minimal d.ts test for JSX usage and the onError signature would help prevent accidental type regressions.
kangju2000
left a comment
There was a problem hiding this comment.
1. The name "Observer" might not align with the actual behavior
"Observer" tends to evoke the observer pattern (subscribe/unsubscribe), but the actual implementation is a Context Provider — it propagates an error callback through Context for ErrorBoundary to consume. There might be a gap between the mental model the name suggests and how it actually works.
2. Could a wrapper component achieve a similar result?
If the core motivation is "apply the same onError to all ErrorBoundaries," a wrapper seems like it could solve this just as well:
const AppErrorBoundary = (props) => (
<ErrorBoundary onError={Sentry.captureReactException} {...props} />
)Observer adds useContext + useCallback to every ErrorBoundary instance for this purpose, and this cost is incurred even when Observer isn't used — I'm curious whether this tradeoff is considered acceptable.
3. If the goal is default props, would DefaultPropsProvider be a more natural fit?
Since suspensive already has DefaultPropsProvider, adding a default onError there might feel more consistent with the existing API. Extending a pattern users already know could be preferable to introducing a new component — what do you think?
I agree. I want to find another candidate for naming.
Default prop should be available to be overridden. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1911 +/- ##
==========================================
+ Coverage 93.22% 93.35% +0.13%
==========================================
Files 42 42
Lines 664 677 +13
Branches 164 164
==========================================
+ Hits 619 632 +13
Misses 42 42
Partials 3 3
🚀 New features to boost your workflow:
|
|
I think this API is similar to TanStack Form's listeners in what it aims to solve — handling side-effects in addition to the actual action (local What do you think about defining it as ref: https://tanstack.com/form/v1/docs/framework/react/guides/listeners
My thought on this — if we support the API with a side-effect-oriented approach, it could be handled more elegantly. For example, think about bubble order. On top of that, allowing propagation to be stopped (e.g. |
new
ErrorBoundary.ObserverErrorBoundary.Observeris a component that observes errors from all nested<ErrorBoundary/>components. It does not catch or handle errors — it simply observes them, making it ideal for integrating with external error reporting tools like Sentry.Motivation
Previously, you had to attach
onErrorprop individually to each<ErrorBoundary/>. To observe errors across the entire app, you had to repeatedly pass the same handler to every ErrorBoundary.AS-IS
TO-BE
Additive (not override)
ErrorBoundary.Observerdoes not override each<ErrorBoundary/>'s ownonError. Both are always called.Features
onError→ inner Observer → outer ObserverErrorBoundary.Observercomponents can be nested, and all will be called@experimental: Marked as an experimental featureChanges
packages/react/src/ErrorBoundary.tsx: AddErrorBoundary.Observerstatic member andErrorObserverContextpackages/react/src/ErrorBoundary.spec.tsx: Add 4 test casesdocs/suspensive.org/src/content/{en,ko}/docs/react/ErrorBoundary.mdx: Add documentation (comparison table, Observer section, Sentry migration guide)