Граница ошибки не дает доступа к ошибке, если это экземпляр класса ошибки

Я столкнулся со странным поведением. Смотри эту скрипку. При использовании React 16 механизма обработки ошибок, а именно Error Boundary, я заметил error Параметр был пустым. После дальнейшего изучения я понял, что это был только тот случай, когда выбрасывался объект Error:

throw new Error('The world is very strange')

Однако при выдаче ошибки вот так:

throw 'The world is very strange'

Ошибка будет доступна в componentDidCatch,

Пожалуйста, кто-нибудь, просветите меня. Я хочу продолжать использовать new Error потому что рекомендуется использовать его, и он должен дать доступ к файлу и номер строки броска.

Давайте посмотрим на код.

class Boundary extends React.Component {
    constructor() {
      super();
      this.state = {}
    }

    componentDidCatch(error, info) {
       this.setState({
        error,
        info,
      })
    }

  render() {
    if (this.state.error) {
       return (
       <div>
         {JSON.stringify(this.state)}
       </div>)
    }
    return this.props.children;
   }
}

class Component extends React.Component {
    render() {
  // Why and what should i do ?
    throw 'This will be available in the error parameter'
    throw new Error('This one will not')
  }
}

class TodoApp extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
    <Boundary>
      <div>
        <Component />
      </div>
    </Boundary>
    )
  }
}

2 ответа

Решение

Бросать строки не рекомендуется, поскольку ошибка обычно является объектом, предпочтительно экземпляром Error,

Нет проблем с метанием Error, Есть проблема с тем, как это обрабатывается:

  if (this.state.error) {
     return (
     <div>
       {JSON.stringify(this.state)}
     </div>)
  }

поскольку error.message неисчислимо, error Стригирован в {}, Это ожидаемое поведение. JSON.stringify не следует полагаться на всестороннее представление объектов - это то, для чего предназначена консоль разработчика.

Текущее представление может быть исправлено путем расширения Error:

class HumanReadableError extends Error {
  toJSON() {
    return `Error: ${this.message}`;
  }
}

а также

throw new HumanReadableError('This will not be available');

Ошибка действительно доступна. Проблема в том, что JSON.stringify не сериализуется Error объекты, и поскольку это то, что вы используете для отображения ошибки, похоже, что ошибка пуста.

Вот обновленная версия вашей скрипки, которая явно выводит state.error.message и это работает.

Другие вопросы по тегам