3

I have an error boundary set at the top of my component tree, like this:

renderApp() {
  return (
    <ErrorBoundary>
      { this.props.children }
    </ErrorBoundary>
  );
}

Should an error find its way up the tree, the error boundary renders a simple error page, passing the error itself as a prop:

componentDidCatch(error, info) {
  this.setState({
    hasError: true,
    error
  });
}

render() {
  if (this.state.hasError) {
    return (
      <ErrorPage error={this.state.error}/>
    );
  }
  return this.props.children;
}

I've started to define custom errors to throw around the application when certain exceptions are raised, simply extending the Error class:

class CustomError extends Error {}

Then in my components, I'm throwing these custom errors, which I'd like to detect in my error page and construct messaging based on their type. E.g., if I'm throwing this error further down in the component tree:

throw new CustomError('This is the custom error message');

I'd like to be able to sniff the type in my error page, and display messaging that's pertinent for that type.

import CustomError from '../../errors/custom-error';

// This code has obviously been edited for brevity's sake

class ErrorPage extends React.Component {
  render() {
    if (this.props.error instanceof CustomError) {
      errorMessage = "A custom error occurred.";
    }
    return <div>{errorMessage}</div>;
  }
}

However, in the error page, React only recognizes that this.props.error is an instanceof Error, not of CustomError. If I throw, say, a TypeError instead of a CustomError, then the error page can detect the error type. But passing the custom error type results in the error page knowing nothing about the type other than that it's an error, which obviously defeats the purpose of defining custom error types. What am I missing here? Is this a bug in React? Any input would be most appreciated.

I discovered this issue using React 16.0.0, have updated to 16.2.0 and the problem persists.

2
  • How are you creating your CustomError? Does it just extend the Error class? For example, class CustomError extends Error? Commented Feb 14, 2018 at 16:28
  • @AnthonyN Yes, exactly. I'll update my description. Thanks for flagging. Commented Feb 14, 2018 at 16:31

2 Answers 2

3

The issue isn't with React, it's with Babel, which I assume you are using. The way classes are compiled doesn't support using instanceof with classes that extend native classes like Error.

You can see an example of that behavior here: https://babeljs.io/repl/#?babili=false&browsers=&build=&builtIns=false&code_lz=MYGwhgzhAEDCCuEAuB7AtgUQE5ZV6ApgB5IEB2AJjNrvgN4C-A3AFDApnLRjQC80ZAgHc4iVJhx4AFAEpW7TihAEAdCBQBzKTwCWnJGDLACKAGajk6GnjlA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=true&fileSize=false&lineWrap=true&presets=es2015%2Creact%2Cstage-2&prettier=false&targets=&version=6.26.0&envVersion=

See this Babel issue for more information: https://github.com/babel/babel/issues/3083

Sign up to request clarification or add additional context in comments.

Comments

1

I created a Github repository that shows how React handles error boundaries.

It seems like React is able to detect CustomError. See this line of code here.

Let me know if this example is representative of what you have.

1 Comment

Thanks for your help with this. Your code is working as advertised. I don't understand why your example works and mine doesn't. I threw up an example on Codepen to illustrate what I'm seeing – any idea why instanceof isn't properly distinguishing between Error and FalsyError? codepen.io/heywilly/pen/wyrKjz

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.