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.
if (inst === null) {
        ops.push('barRef detach');
        throw new Error('Detach error');
      }
      ops.push('barRef attach');
    }
    function Foo(props) {
      return (
        <div>
          {props.hide ? null : <Bar ref={barRef} />}
        </div>
      );
    }
    ReactNoop.render(<Foo />);
    ReactNoop.flush();
    expect(ops).toEqual(['barRef attach']);
    expect(ReactNoop.getChildren()).toEqual([div(span('Bar'))]);
    ops = [];
    
    ReactNoop.render(<Foo hide={true} />);
    expect(() => ReactNoop.flush()).toThrow('Detach error');
    expect(ops).toEqual([
      'barRef detach',
      
      'Bar unmount',
    ]);
    
    expect(ReactNoop.getChildren()).toEqual([]);
  });