Skip to content

feat: add ErrorBoundary around route tree#4

Merged
alichherawalla merged 6 commits into
mainfrom
feat/error-boundary
Feb 18, 2026
Merged

feat: add ErrorBoundary around route tree#4
alichherawalla merged 6 commits into
mainfrom
feat/error-boundary

Conversation

@alichherawalla
Copy link
Copy Markdown
Contributor

Summary

  • Adds src/ErrorBoundary.tsx — React class component using getDerivedStateFromError to catch render errors
  • Wraps the <Routes> tree in App.tsx so any unhandled page crash shows a friendly fallback instead of a blank white screen
  • Fallback shows the error message and a "Try again" button that resets state (no full page reload needed)

Tests

4 new unit tests in ErrorBoundary.test.tsx:

  • 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

All 17 tests pass.

Test plan

  • CI green
  • Navigate to a broken route locally — fallback renders, no white screen
  • Click "Try again" — resets correctly

🤖 Generated with Claude Code

alichherawalla and others added 4 commits February 18, 2026 11:53
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>
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @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

  • ErrorBoundary Component: Introduced a new React class component, src/ErrorBoundary.tsx, which uses getDerivedStateFromError to gracefully catch rendering errors within its children.
  • Route Tree Protection: Wrapped the main <Routes> tree in App.tsx with the new ErrorBoundary to prevent unhandled page crashes from resulting in a blank screen.
  • User-Friendly Fallback: Implemented a fallback UI that displays a clear error message and includes a "Try again" button, allowing users to reset the component state without a full page reload.
  • Comprehensive Testing: Added four new unit tests in ErrorBoundary.test.tsx to verify the component's behavior, including rendering children, showing fallback UI, preventing re-throws, and correctly resetting state.

🧠 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
  • packages/web/src/App.tsx
    • Imported the new ErrorBoundary component.
    • Wrapped the <Routes> component with ErrorBoundary to provide application-wide error handling for the route tree.
  • packages/web/src/ErrorBoundary.test.tsx
    • Added a new test file for the ErrorBoundary component.
    • Included tests for rendering children, displaying fallback UI on error, preventing error re-propagation, and resetting state.
  • packages/web/src/ErrorBoundary.tsx
    • Created a new React class component implementing the ErrorBoundary pattern.
    • Defined getDerivedStateFromError to update state on error and render to display either children or a fallback UI.
    • Implemented a "Try again" button to reset the error state.
Activity
  • A new ErrorBoundary component was created to handle runtime errors in the React component tree.
  • The main Routes component in App.tsx was wrapped with the ErrorBoundary to provide global error handling for navigation.
  • Comprehensive unit tests were added for the ErrorBoundary component, covering various error scenarios and recovery mechanisms.
  • The pull request author provided a detailed summary, test instructions, and a test plan for verification.
  • The changes were generated with Claude Code, indicating AI assistance in development.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

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>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

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.

Comment on lines +18 to +20
return { hasError: true };
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

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);
  }

Comment on lines +25 to +36
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 })}
>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

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>
@alichherawalla alichherawalla merged commit 10e7548 into main Feb 18, 2026
1 check passed
@alichherawalla alichherawalla deleted the feat/error-boundary branch February 18, 2026 06:28
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.

1 participant