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.
it('handles error thrown by host config while working on failed root', () => {
    ReactNoop.simulateErrorInHostConfig(() => {
      ReactNoop.render(<span />);
      expect(() => ReactNoop.flush()).toThrow('Error in host config.');
    });
  });
  it('handles error thrown by top-level callback', () => {
    ReactNoop.render(<div />, () => {
      throw new Error('Error!');
    });
    expect(() => ReactNoop.flush()).toThrow('Error!');
  });
  describe('ReactFiberErrorLogger', () => {
    function initReactFiberErrorLoggerMock(mock) {
      jest.resetModules();
      if (mock) {
        jest.mock('ReactFiberErrorLogger');
      } else {
        jest.unmock('ReactFiberErrorLogger');
      }
      React = require('react');
      ReactNoop = require('react-noop-renderer');
    }
    function normalizeCodeLocInfo(str) {
      return str && str.replace(/\(at .+?:\d+\)/g, '(at **)');
    }
    it('should log errors that occur during the begin phase', () => {
      initReactFiberErrorLoggerMock();
      spyOn(console, 'error');
      class ErrorThrowingComponent extends React.Component {