feat: add ErrorBoundary around route tree#4
Conversation
Class component using getDerivedStateFromError to catch render errors. Shows a friendly fallback with the error message and a "Try again" button that resets the error state, allowing recovery without a full page reload. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Any unhandled render error in a page component now shows the ErrorBoundary fallback instead of a blank white screen. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Renders children when no error occurs - Shows fallback UI with error message when a child throws - Does not re-throw to parent - Resets and re-renders children when "Try again" is clicked Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Class component wrapping getDerivedStateFromError + componentDidCatch. Renders a friendly fallback (generic message + Try again button) instead of a blank white screen when any child component throws during render. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary of ChangesHello @alichherawalla, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the application's robustness by integrating a React ErrorBoundary. This ensures that any unexpected runtime errors within the application's routing structure are gracefully handled, providing a consistent and user-friendly experience instead of a disruptive crash. The implementation includes a clear fallback UI and a mechanism for users to attempt recovery. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
ErrorBoundary shows a static generic message, not the raw error.message, so update the assertion accordingly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces an ErrorBoundary component to gracefully handle rendering errors, which is a significant improvement for application stability and user experience. The implementation is well-done, and the new tests are thorough. My feedback focuses on enhancing the new ErrorBoundary component. I've suggested adding componentDidCatch for error logging, which is vital for production monitoring. I also recommended moving inline styles to a separate stylesheet to improve maintainability.
| return { hasError: true }; | ||
| } | ||
|
|
There was a problem hiding this comment.
While getDerivedStateFromError is great for updating state to render a fallback UI, it's also crucial to log the error for debugging and monitoring purposes. You should implement componentDidCatch to handle side-effects like logging the error to the console or an external service. Without this, errors caught by this boundary will not be reported, making it difficult to track issues in production.
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
// TODO: In a real app, you'd send this to an error reporting service
console.error("ErrorBoundary caught an error:", error, errorInfo);
}
| render(): ReactNode { | ||
| if (this.state.hasError) { | ||
| return ( | ||
| <div style={{ textAlign: 'center', padding: '60px 20px' }}> | ||
| <h2>Something went wrong.</h2> | ||
| <p style={{ color: '#666', marginTop: '8px' }}> | ||
| An unexpected error occurred. Please refresh the page to try again. | ||
| </p> | ||
| <button | ||
| style={{ marginTop: '20px' }} | ||
| onClick={() => this.setState({ hasError: false })} | ||
| > |
There was a problem hiding this comment.
For better maintainability and separation of concerns, it's recommended to avoid inline styles. Consider moving these styles to a dedicated CSS or CSS-in-JS file and using class names instead. This makes styles more reusable and easier to manage, especially as the application grows.
For example, you could create an ErrorBoundary.css file and import it:
ErrorBoundary.css
.error-boundary-fallback {
text-align: center;
padding: 60px 20px;
}
.error-message {
color: #666;
margin-top: 8px;
}
.retry-button {
margin-top: 20px;
}ErrorBoundary.tsx
import './ErrorBoundary.css';
// ...
<div className="error-boundary-fallback">
<h2>Something went wrong.</h2>
<p className="error-message">
{this.state.error?.message ?? 'An unexpected error occurred.'}
</p>
<button
onClick={() => this.setState({ hasError: false, error: null })}
className="retry-button"
>
Try again
</button>
</div>React class render() legitimately returns JSX on one path and ReactNode on the other — this is expected pattern, not a refactor target. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
src/ErrorBoundary.tsx— React class component usinggetDerivedStateFromErrorto catch render errors<Routes>tree inApp.tsxso any unhandled page crash shows a friendly fallback instead of a blank white screenTests
4 new unit tests in
ErrorBoundary.test.tsx:All 17 tests pass.
Test plan
🤖 Generated with Claude Code