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.
Error boundaries that captured an error during the current commit.
  let commitPhaseBoundaries: Set<Fiber> | null = null;
  let firstUncaughtError: mixed | null = null;
  let didFatal: boolean = false;
  let isCommitting: boolean = false;
  let isUnmounting: boolean = false;
   Use these to prevent an infinite loop of nested updates
  const NESTED_UPDATE_LIMIT = 1000;
  let nestedUpdateCount = 0;
  function resetContextStack() {
    
    reset();
    
    resetContext();
    resetHostContainer();
  }
   resetNextUnitOfWork mutates the current priority context. It is reset after
   after the workLoop exits, so never call resetNextUnitOfWork from outside
   the work loop.
  function resetNextUnitOfWork() {
    
    while (
      nextScheduledRoot !== null &&
      nextScheduledRoot.current.pendingWorkPriority === NoWork
    ) {
      
      nextScheduledRoot.isScheduled = false;
      
      
      const next = nextScheduledRoot.nextScheduledRoot;