mui / mui/material-ui

[ErrorBoundary] New ErrorBoundary Component

Open
#19,945 6 comments 12 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

scope: new proposal type: new feature waiting for 👍
Dominant language
JavaScript
Stars
99.1k
Forks
32.5k
Avg merge
2d 17h
Merged PRs (30d)
106

Description

This ticket is to track ideas/rationale for material-ui including an ErrorBoundary component.

I would like to contribute this component to material-ui, as described below.

  • I have searched the issues of this repository and believe that this is not a duplicate.

Summary 💡

ErrorBoundaries are a React 16+ specific feature that uses the componentDidCatch API for handling uncaught errors without unmounting the whole React component tree.

This ticket exists to request feedback and ideas for a material-ui-provided ErrorBoundary component.

Examples 🌈

The react-ui-roundup tracks ErrorBoundaries, and it appears that there are just 3 implementations:

For convenience, I've linked to the actual code for these three here:

  • Elastic's code: This one is the simplest (and, best looking, in my opinion). No props, just catches the error as you might expect.
  • AntD's code: This is implemented by adapting the Alert component (I do not think we should do this in this project, btw). It therefore accepts a title and description prop (both strings), but not for passing in a custom fallback component, which is a bummer.
  • Carbon Design's code: This one, although the storybook example they have is a bit unfortunate (it doesn't even show an error or callstack..???), it's actually the most flexible of the bunch. It allows passing in a fallback component via a fallback prop. The only downside here is that the actual error and componentStack are not accessible because they are not passed in to the fallback component.

So basically, I'm suggesting a mashup of the above 3, the looks of Eui, the simple string api of AntD, the flexible fallback (if you really need or want it), and two more little additions (they're related).

I have done a few of these ErrorBoundary components for various projects in the past and one thing I ALWAYS end up needing is a little section at the bottom of the callstack where I can tell the user something like:

Oops! Something went wrong. Please contact support at 1-800-867-5309

Or (better) sometimes it's appropriate to have a button that the user can click to contact support that will then open up something like Intercom, will start an email with some useful information pre-populated, or will send an error report dialog with something like getSentry.

Speaking of which, mature codebases will often be tracking errors of this sort with something like getSentry, and the onCatch prop exists as a simple callback that will allow the user to trigger some analytics (or other change) if an error state is to occur.

I propose the following API:

import { ReactNode, ErrorInfo } from 'react';

interface ErrorBoundaryProps {
  /**
   * This inserts a section below the call stack (or fallback) but within the ErrorBoundary that you can use to provide the users with more info (such as a support phone number to call) or
   */
  actions?: ReactNode;
  
  /**
   * Can be overridden by providing a `fallback` prop.
   */
  description?: string | ((componentStack: string) => string);

  /**
   * forces the ErrorBoundary to render when debug is `true`
   */
  debug?: boolean;

  /**
   * This matches the arguments of `componentDidCatch`.
   * If provided, overrides `title` and `description` props by occupying the space where the title and description are.
  */
  renderFallback?: (error: Error, errorInfo: ErrorInfo) => ReactNode;

  /**
   * This matches the arguments of `componentDidCatch`.
   * This callback is useful for enabling sending error information to analytics.
   */
  onCatch?: (error: Error, errorInfo: ErrorInfo) => void;

  /**
   * Provide a string to override, or a function that receives the name of the error
   */
  title?: string | ((errorTitle: string) => string);
}

const ErrorBoundary: FC<ErrorBoundary> = props => { ... }

As far as styling goes, I think Elastic's looks best. Perhaps we can just play around with material-ui internals and quickly find something suitable that works in both light and dark themes.

Motivation 🔦

this was mentioned by @oliviertassinari https://github.com/mui-org/material-ui/issues/19744#issuecomment-593408040 in a comment about improving user experience.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The issue names no repository file, test, or entry point. Start by reviewing React's ErrorBoundary and componentDidCatch documentation, along with the linked Elastic, AntD, and Carbon implementations. The proposed API, styling, and component scope still need maintainer agreement before implementation can be considered complete.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.