Three points from discussion in https://github.com/reactjs/react-redux/issues/756:

* Due to https://bugs.chromium.org/p/chromium/issues/detail?id=701371, environments like CodeSandbox show `Error: null` in our “React caught an error” warning. Let’s consider skipping both as they’re not very useful and look like a bug. `Error: null` looks like a separate error and draws attention away from the real error just above.

* In any case we should probably not print `The error was thrown at:` if we don’t have a JS stack.

* There is a related issue. What do we pass to error boundary if we caught `null`? It seems that most error boundaries will intuitively do something like `if (this.state.error)` or read `error.message`, which `null` will break. There are other falsy values too like `''` and `undefined`. My proposal is we always wrap primitives into our own `Error` objects that we pass to the boundary.
that capture them. We mostly use this Map as a Set; it's a Map only to
       avoid adding a field to Fiber to store the error.
      if (capturedErrors === null) {
        capturedErrors = new Map();
      }
      capturedErrors.set(boundary, {
        componentName,
        componentStack,
        error,
        errorBoundary: errorBoundaryFound ? boundary.stateNode : null,
        errorBoundaryFound,
        errorBoundaryName,
        willRetry,
      });
       If we're in the commit phase, defer scheduling an update on the
       boundary until after the commit is complete
      if (isCommitting) {
        if (commitPhaseBoundaries === null) {
          commitPhaseBoundaries = new Set();
        }
        commitPhaseBoundaries.add(boundary);
      } else {
         
         
         
         
        scheduleErrorRecovery(boundary);
      }
      return boundary;
    } else if (firstUncaughtError === null) {