suspensive
suspensive copied to clipboard
Add development mode logging for unexpected errors in ErrorBoundary catch block
Problem
The empty catch block in the matchError function silently swallowed all errors without any fallback behavior or logging, making it difficult to debug unexpected issues during development.
try {
if (errorMatcher === Error || errorMatcher.prototype instanceof Error) {
return error instanceof errorMatcher
}
} catch {
// Silent catch - no way to know if unexpected errors occur
}
Solution
Enhanced the catch block to:
- Capture the error for inspection
- Add comprehensive documentation explaining expected vs unexpected error types
- Log unexpected errors (non-TypeError) in development mode only
try {
if (errorMatcher === Error || errorMatcher.prototype instanceof Error) {
return error instanceof errorMatcher
}
} catch (err) {
// If accessing prototype throws, it's not a constructor. This can happen with proxy objects or in restricted environments.
// Only TypeError is expected here; log unexpected errors in development mode.
if (process.env.NODE_ENV !== 'production') {
if (!(err instanceof TypeError)) {
console.error('Unexpected error in matchError when accessing prototype:', err)
}
}
}
Benefits
- Better debugging: Developers can now see unexpected errors during development
- Production-safe: No logging overhead in production builds
- Well-documented: Clear explanation of why TypeError is expected and other errors are not
- Non-breaking: Maintains existing behavior while adding helpful diagnostics
Testing
Added 3 comprehensive test cases to verify:
- Unexpected errors (RangeError) are logged in development mode
- Expected errors (TypeError) are NOT logged in development mode
- No errors are logged in production mode
All existing tests continue to pass (32 tests total).
Fixes #1760
Original prompt
This section details on the original issue you should resolve
<issue_title>The empty catch block silently swallows all errors without any fallback behavior or logging. Consider adding a comment explaining what specific errors are expected (like accessing prototype on Proxy objects) and potentially log unexpected errors in development mode.</issue_title> <issue_description>The empty catch block silently swallows all errors without any fallback behavior or logging. Consider adding a comment explaining what specific errors are expected (like accessing prototype on Proxy objects) and potentially log unexpected errors in development mode.
} catch (err) { // If accessing prototype throws, it's not a constructor. This can happen with Proxy objects or in restricted environments. // Only TypeError is expected here; log unexpected errors in development mode. if (process.env.NODE_ENV !== 'production') { if (!(err instanceof TypeError)) { console.error('Unexpected error in matchError when accessing prototype:', err); } }Originally posted by @Copilot in https://github.com/toss/suspensive/pull/1760#discussion_r2427857869 </issue_description>
Comments on the Issue (you are @copilot in this section)
Fixes toss/suspensive#1778
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.
🦋 Changeset detected
Latest commit: 93ba79da7ba50020fa50df95f4b7d75fa0847174
The changes in this PR will be included in the next version bump.
This PR includes changesets to release 7 packages
| Name | Type |
|---|---|
| @suspensive/react | Patch |
| @suspensive/react-dom | Patch |
| @suspensive/react-query | Patch |
| @suspensive/react-query-4 | Patch |
| @suspensive/react-query-5 | Patch |
| @suspensive/jotai | Patch |
| @suspensive/codemods | Patch |
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.
| Project | Deployment | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| v2.suspensive.org | Preview | Comment | Oct 15, 2025 6:02am | |
| v3.suspensive.org | Preview | Comment | Oct 15, 2025 6:02am | |
| visualization.suspensive.org | Preview | Comment | Oct 15, 2025 6:02am |
People can be co-author:
| Candidate | Reasons | Count | Add this as commit message |
|---|---|---|---|
| @Copilot | https://github.com/toss/suspensive/pull/1781 | 1 | Co-authored-by: Copilot <[email protected]> |
Size Change: +49 B (+0.06%)
Total Size: 80.3 kB
| Filename | Size | Change |
|---|---|---|
packages/react/dist/ErrorBoundary-********.js |
2.13 kB | +51 B (+2.45%) |
packages/react/dist/ErrorBoundary.cjs |
193 B | -1 B (-0.52%) |
packages/react/dist/index.js |
393 B | -1 B (-0.25%) |
ℹ️ View Unchanged
| Filename | Size |
|---|---|
packages/jotai/dist/Atom-********.cjs |
383 B |
packages/jotai/dist/Atom-********.js |
265 B |
packages/jotai/dist/Atom.cjs |
93 B |
packages/jotai/dist/Atom.js |
80 B |
packages/jotai/dist/AtomValue-********.js |
241 B |
packages/jotai/dist/AtomValue-********.cjs |
375 B |
packages/jotai/dist/AtomValue.cjs |
99 B |
packages/jotai/dist/AtomValue.js |
85 B |
packages/jotai/dist/chunk-********.cjs |
542 B |
packages/jotai/dist/index.cjs |
151 B |
packages/jotai/dist/index.js |
125 B |
packages/jotai/dist/SetAtom-********.cjs |
368 B |
packages/jotai/dist/SetAtom-********.js |
239 B |
packages/jotai/dist/SetAtom.cjs |
97 B |
packages/jotai/dist/SetAtom.js |
83 B |
packages/react-dom/dist/FadeIn-********.js |
391 B |
packages/react-dom/dist/FadeIn-********.cjs |
506 B |
packages/react-dom/dist/FadeIn.cjs |
131 B |
packages/react-dom/dist/FadeIn.js |
116 B |
packages/react-dom/dist/index.cjs |
174 B |
packages/react-dom/dist/index.js |
146 B |
packages/react-dom/dist/InView-********.cjs |
747 B |
packages/react-dom/dist/InView-********.js |
664 B |
packages/react-dom/dist/InView.cjs |
113 B |
packages/react-dom/dist/InView.js |
99 B |
packages/react-dom/dist/useFadeIn-********.js |
425 B |
packages/react-dom/dist/useFadeIn-********.cjs |
512 B |
packages/react-dom/dist/useFadeIn.cjs |
122 B |
packages/react-dom/dist/useFadeIn.js |
107 B |
packages/react-dom/dist/useInView-********.cjs |
2.06 kB |
packages/react-dom/dist/useInView-********.js |
1.61 kB |
packages/react-dom/dist/useInView.cjs |
99 B |
packages/react-dom/dist/useInView.js |
85 B |
packages/react-native/dist/index.cjs |
98 B |
packages/react-native/dist/index.js |
84 B |
packages/react-native/dist/TestText-********.cjs |
707 B |
packages/react-native/dist/TestText-********.js |
211 B |
packages/react-native/dist/TestText.cjs |
98 B |
packages/react-native/dist/TestText.js |
84 B |
packages/react-query-4/dist/chunk-********.cjs |
542 B |
packages/react-query-4/dist/index.cjs |
522 B |
packages/react-query-4/dist/index.js |
439 B |
packages/react-query-4/dist/infiniteQueryOptions-********.js |
308 B |
packages/react-query-4/dist/infiniteQueryOptions-********.cjs |
431 B |
packages/react-query-4/dist/infiniteQueryOptions.cjs |
111 B |
packages/react-query-4/dist/infiniteQueryOptions.js |
96 B |
packages/react-query-4/dist/IsFetching-********.js |
268 B |
packages/react-query-4/dist/IsFetching-********.cjs |
408 B |
packages/react-query-4/dist/IsFetching.cjs |
100 B |
packages/react-query-4/dist/IsFetching.js |
86 B |
packages/react-query-4/dist/Mutation-********.cjs |
447 B |
packages/react-query-4/dist/Mutation-********.js |
314 B |
packages/react-query-4/dist/Mutation.cjs |
135 B |
packages/react-query-4/dist/Mutation.js |
120 B |
packages/react-query-4/dist/mutationOptions-********.js |
153 B |
packages/react-query-4/dist/mutationOptions-********.cjs |
210 B |
packages/react-query-4/dist/mutationOptions.cjs |
103 B |
packages/react-query-4/dist/mutationOptions.js |
89 B |
packages/react-query-4/dist/objectWithoutProperties-********.js |
370 B |
packages/react-query-4/dist/objectWithoutProperties-********.cjs |
413 B |
packages/react-query-4/dist/PrefetchInfiniteQuery-********.js |
408 B |
packages/react-query-4/dist/PrefetchInfiniteQuery-********.cjs |
521 B |
packages/react-query-4/dist/PrefetchInfiniteQuery.cjs |
131 B |
packages/react-query-4/dist/PrefetchInfiniteQuery.js |
115 B |
packages/react-query-4/dist/PrefetchQuery-********.js |
396 B |
packages/react-query-4/dist/PrefetchQuery-********.cjs |
513 B |
packages/react-query-4/dist/PrefetchQuery.cjs |
122 B |
packages/react-query-4/dist/PrefetchQuery.js |
105 B |
packages/react-query-4/dist/QueryClientConsumer-********.cjs |
422 B |
packages/react-query-4/dist/QueryClientConsumer-********.js |
283 B |
packages/react-query-4/dist/QueryClientConsumer.cjs |
107 B |
packages/react-query-4/dist/QueryClientConsumer.js |
92 B |
packages/react-query-4/dist/queryOptions-********.cjs |
424 B |
packages/react-query-4/dist/queryOptions-********.js |
304 B |
packages/react-query-4/dist/queryOptions.cjs |
102 B |
packages/react-query-4/dist/queryOptions.js |
88 B |
packages/react-query-4/dist/SuspenseInfiniteQuery-********.cjs |
708 B |
packages/react-query-4/dist/SuspenseInfiniteQuery-********.js |
563 B |
packages/react-query-4/dist/SuspenseInfiniteQuery.cjs |
147 B |
packages/react-query-4/dist/SuspenseInfiniteQuery.js |
133 B |
packages/react-query-4/dist/SuspenseQueries-********.cjs |
636 B |
packages/react-query-4/dist/SuspenseQueries-********.js |
493 B |
packages/react-query-4/dist/SuspenseQueries.cjs |
105 B |
packages/react-query-4/dist/SuspenseQueries.js |
91 B |
packages/react-query-4/dist/SuspenseQuery-********.cjs |
690 B |
packages/react-query-4/dist/SuspenseQuery-********.js |
552 B |
packages/react-query-4/dist/SuspenseQuery.cjs |
140 B |
packages/react-query-4/dist/SuspenseQuery.js |
125 B |
packages/react-query-4/dist/usePrefetchInfiniteQuery-********.js |
404 B |
packages/react-query-4/dist/usePrefetchInfiniteQuery-********.cjs |
518 B |
packages/react-query-4/dist/usePrefetchInfiniteQuery.cjs |
115 B |
packages/react-query-4/dist/usePrefetchInfiniteQuery.js |
100 B |
packages/react-query-4/dist/usePrefetchQuery-********.js |
395 B |
packages/react-query-4/dist/usePrefetchQuery-********.cjs |
513 B |
packages/react-query-4/dist/usePrefetchQuery.cjs |
106 B |
packages/react-query-4/dist/usePrefetchQuery.js |
92 B |
packages/react-query-4/dist/useSuspenseInfiniteQuery-********.cjs |
438 B |
packages/react-query-4/dist/useSuspenseInfiniteQuery-********.js |
313 B |
packages/react-query-4/dist/useSuspenseInfiniteQuery.cjs |
115 B |
packages/react-query-4/dist/useSuspenseInfiniteQuery.js |
100 B |
packages/react-query-4/dist/useSuspenseQueries-********.js |
307 B |
packages/react-query-4/dist/useSuspenseQueries-********.cjs |
432 B |
packages/react-query-4/dist/useSuspenseQueries.cjs |
109 B |
packages/react-query-4/dist/useSuspenseQueries.js |
94 B |
packages/react-query-4/dist/useSuspenseQuery-********.js |
305 B |
packages/react-query-4/dist/useSuspenseQuery-********.cjs |
431 B |
packages/react-query-4/dist/useSuspenseQuery.cjs |
106 B |
packages/react-query-4/dist/useSuspenseQuery.js |
92 B |
packages/react-query-5/dist/chunk-********.cjs |
542 B |
packages/react-query-5/dist/index.cjs |
519 B |
packages/react-query-5/dist/index.js |
429 B |
packages/react-query-5/dist/infiniteQueryOptions-********.js |
303 B |
packages/react-query-5/dist/infiniteQueryOptions-********.cjs |
427 B |
packages/react-query-5/dist/infiniteQueryOptions.cjs |
111 B |
packages/react-query-5/dist/infiniteQueryOptions.js |
96 B |
packages/react-query-5/dist/IsFetching-********.js |
349 B |
packages/react-query-5/dist/IsFetching-********.cjs |
484 B |
packages/react-query-5/dist/IsFetching.cjs |
137 B |
packages/react-query-5/dist/IsFetching.js |
122 B |
packages/react-query-5/dist/Mutation-********.cjs |
445 B |
packages/react-query-5/dist/Mutation-********.js |
313 B |
packages/react-query-5/dist/Mutation.cjs |
135 B |
packages/react-query-5/dist/Mutation.js |
120 B |
packages/react-query-5/dist/mutationOptions-********.cjs |
423 B |
packages/react-query-5/dist/mutationOptions-********.js |
302 B |
packages/react-query-5/dist/mutationOptions.cjs |
103 B |
packages/react-query-5/dist/mutationOptions.js |
89 B |
packages/react-query-5/dist/objectWithoutProperties-********.cjs |
413 B |
packages/react-query-5/dist/objectWithoutProperties-********.js |
370 B |
packages/react-query-5/dist/PrefetchInfiniteQuery-********.js |
399 B |
packages/react-query-5/dist/PrefetchInfiniteQuery-********.cjs |
536 B |
packages/react-query-5/dist/PrefetchInfiniteQuery.cjs |
112 B |
packages/react-query-5/dist/PrefetchInfiniteQuery.js |
97 B |
packages/react-query-5/dist/PrefetchQuery-********.cjs |
529 B |
packages/react-query-5/dist/PrefetchQuery-********.js |
390 B |
packages/react-query-5/dist/PrefetchQuery.cjs |
103 B |
packages/react-query-5/dist/PrefetchQuery.js |
89 B |
packages/react-query-5/dist/QueryClientConsumer-********.cjs |
423 B |
packages/react-query-5/dist/QueryClientConsumer-********.js |
284 B |
packages/react-query-5/dist/QueryClientConsumer.cjs |
107 B |
packages/react-query-5/dist/QueryClientConsumer.js |
92 B |
packages/react-query-5/dist/queryOptions-********.cjs |
421 B |
packages/react-query-5/dist/queryOptions-********.js |
297 B |
packages/react-query-5/dist/queryOptions.cjs |
102 B |
packages/react-query-5/dist/queryOptions.js |
88 B |
packages/react-query-5/dist/SuspenseInfiniteQuery-********.js |
562 B |
packages/react-query-5/dist/SuspenseInfiniteQuery-********.cjs |
709 B |
packages/react-query-5/dist/SuspenseInfiniteQuery.cjs |
148 B |
packages/react-query-5/dist/SuspenseInfiniteQuery.js |
133 B |
packages/react-query-5/dist/SuspenseQueries-********.cjs |
652 B |
packages/react-query-5/dist/SuspenseQueries-********.js |
506 B |
packages/react-query-5/dist/SuspenseQueries.cjs |
105 B |
packages/react-query-5/dist/SuspenseQueries.js |
91 B |
packages/react-query-5/dist/SuspenseQuery-********.cjs |
687 B |
packages/react-query-5/dist/SuspenseQuery-********.js |
540 B |
packages/react-query-5/dist/SuspenseQuery.cjs |
141 B |
packages/react-query-5/dist/SuspenseQuery.js |
125 B |
packages/react-query-5/dist/usePrefetchInfiniteQuery-********.js |
307 B |
packages/react-query-5/dist/usePrefetchInfiniteQuery-********.cjs |
433 B |
packages/react-query-5/dist/usePrefetchInfiniteQuery.cjs |
115 B |
packages/react-query-5/dist/usePrefetchInfiniteQuery.js |
100 B |
packages/react-query-5/dist/usePrefetchQuery-********.cjs |
424 B |
packages/react-query-5/dist/usePrefetchQuery-********.js |
302 B |
packages/react-query-5/dist/usePrefetchQuery.cjs |
106 B |
packages/react-query-5/dist/usePrefetchQuery.js |
92 B |
packages/react-query-5/dist/useSuspenseInfiniteQuery-********.js |
307 B |
packages/react-query-5/dist/useSuspenseInfiniteQuery-********.cjs |
428 B |
packages/react-query-5/dist/useSuspenseInfiniteQuery.cjs |
115 B |
packages/react-query-5/dist/useSuspenseInfiniteQuery.js |
100 B |
packages/react-query-5/dist/useSuspenseQueries-********.js |
301 B |
packages/react-query-5/dist/useSuspenseQueries-********.cjs |
424 B |
packages/react-query-5/dist/useSuspenseQueries.cjs |
109 B |
packages/react-query-5/dist/useSuspenseQueries.js |
94 B |
packages/react-query-5/dist/useSuspenseQuery-********.cjs |
423 B |
packages/react-query-5/dist/useSuspenseQuery-********.js |
298 B |
packages/react-query-5/dist/useSuspenseQuery.cjs |
106 B |
packages/react-query-5/dist/useSuspenseQuery.js |
92 B |
packages/react-query/dist/chunk-********.cjs |
542 B |
packages/react-query/dist/index.cjs |
381 B |
packages/react-query/dist/index.js |
190 B |
packages/react-query/dist/v4.cjs |
381 B |
packages/react-query/dist/v4.js |
190 B |
packages/react-query/dist/v5.cjs |
381 B |
packages/react-query/dist/v5.js |
190 B |
packages/react/dist/chunk-********.cjs |
542 B |
packages/react/dist/ClientOnly-********.js |
529 B |
packages/react/dist/ClientOnly-********.cjs |
645 B |
packages/react/dist/ClientOnly.cjs |
159 B |
packages/react/dist/ClientOnly.js |
142 B |
packages/react/dist/DefaultProps-********.cjs |
1.03 kB |
packages/react/dist/DefaultProps-********.js |
919 B |
packages/react/dist/DefaultProps.cjs |
163 B |
packages/react/dist/DefaultProps.js |
147 B |
packages/react/dist/DefaultPropsContexts-********.cjs |
372 B |
packages/react/dist/DefaultPropsContexts-********.js |
250 B |
packages/react/dist/Delay-********.js |
1.02 kB |
packages/react/dist/Delay-********.cjs |
1.13 kB |
packages/react/dist/Delay.cjs |
179 B |
packages/react/dist/Delay.js |
161 B |
packages/react/dist/ErrorBoundary-********.cjs |
2.24 kB |
packages/react/dist/ErrorBoundary.js |
175 B |
packages/react/dist/ErrorBoundaryGroup-********.cjs |
1.23 kB |
packages/react/dist/ErrorBoundaryGroup-********.js |
1.1 kB |
packages/react/dist/ErrorBoundaryGroup.cjs |
182 B |
packages/react/dist/ErrorBoundaryGroup.js |
161 B |
packages/react/dist/index.cjs |
459 B |
packages/react/dist/lazy-********.js |
1.98 kB |
packages/react/dist/lazy-********.cjs |
2.1 kB |
packages/react/dist/lazy.cjs |
191 B |
packages/react/dist/lazy.js |
171 B |
packages/react/dist/noop-********.js |
138 B |
packages/react/dist/noop-********.cjs |
201 B |
packages/react/dist/objectSpread2-********.js |
771 B |
packages/react/dist/objectSpread2-********.cjs |
807 B |
packages/react/dist/objectWithoutProperties-********.js |
370 B |
packages/react/dist/objectWithoutProperties-********.cjs |
413 B |
packages/react/dist/Suspense-********.cjs |
950 B |
packages/react/dist/Suspense-********.js |
829 B |
packages/react/dist/Suspense.cjs |
226 B |
packages/react/dist/Suspense.js |
207 B |
packages/react/dist/SuspensiveError-********.cjs |
518 B |
packages/react/dist/SuspensiveError-********.js |
428 B |
packages/react/dist/useIsClient-********.cjs |
350 B |
packages/react/dist/useIsClient-********.js |
243 B |
packages/react/dist/useIsClient.cjs |
117 B |
packages/react/dist/useIsClient.js |
101 B |