DEV Community

Cover image for Error Boundary for wrong props or how I hacked prop-types package
Kiryl Henets
Kiryl Henets

Posted on

Error Boundary for wrong props or how I hacked prop-types package

Hi everyone! Not so long time ago my tech-lead at work gave me a task to create an Error Boundary for wrong prop-types. As we know, prop-types package throws usual console warnings if some components receive wrong props. But we needed it to throw an Error.
There was no information about handling prop-types errors on the internet, so I decided to look into the source code of the prop-types package.
And my attention was riveted by one interesting constant in the ReactPropTypesSecret.js file. That's it:
SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED
Looks funny, yeah? 😄
So after laughing, I tried to figure out what's the sense of this constant. And I succeed.
In the file factoryWithTypeCheckers.js I found function, that checks single prop-type (you give the reference to this function each time when you write propTypes for your component. For example, PropTypes.number calls this function for the number prop-type).
That's how it looks:
factoryWithTypeCheckers.js
And we have to pay attention to the last argument of this function - secret. And if we pass the constant that we found in the previous step there - we will get access to hidden features of prop-types! In this case, our function will return the object of prop-types error (if there is no error it returns null).
So with the usage of this knowledge, I created my own high-ordered component, that takes a component as an argument (and this component has to have errorBoundary prop. This is a component, that our HOC will render if props are not valid). That's how it looks:

import React from 'react';
import SECRET from 'prop-types/lib/ReactPropTypesSecret';

const propTypesChecker = (Component) => (props) => {
  const analysis = Object.keys(Component.propTypes).map((key) => {
    const validator = Component.propTypes[key];
    return validator(props, key, Component.name, '', null, SECRET);
  });

  const errors = analysis.filter((error) => error !== null).map((error) => error.message);
  const arePropsValid = errors.length === 0;
  const ErrorBoundary = props.errorBoundary;

  return (
    arePropsValid
      ? <Component {...props} />
      : <ErrorBoundary errors={errors} />
  );
};

export default propTypesChecker;

The main function here is the analysis function. Here we use ReactPropTypesSecret in order to get access to error objects. And this function just returns all the error messages after checking PropTypes.

And I created NPM-package, so you don`t need to write this on your own :)

My package on NPM: Click!
Source code: Click!

Top comments (0)