Как я могу заставить мою ошибку выборки отображать код состояния http?

#javascript #reactjs #http #express #fetch

#javascript #reactjs #http #выразить #выборка

Вопрос:

У меня есть компонент react, и я выполняю сетевой вызов для настройки состояния. В конечном итоге я хочу передать это другим дочерним компонентам, но на данный момент я просто заставляю систему работать.

Я пытаюсь правильно перехватывать ошибки при вызове моей серверной части (экспресс-сервер в приложении). Я попытался принудительно вызвать ошибку, извлекая данные из конечной точки, которая не существует. Это должно выдавать значение 404, поскольку оно не существует, верно? Как я могу заставить эту ошибку появиться в операторе catch? Прямо сейчас моя ошибка SyntaxError: Unexpected token < in JSON at position 0 at eval (app.js:61)

 export default class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      data: null
    };
  }

  componentDidMount() { 
    fetch('/api/wrong_endpoint').then((data) => {
      return data.json();
    }).then((body) => {
      this.setState({data: body})
    }).catch(err => console.log(err));

  }

  render() {
    console.log('logging the states');
    console.log(this.state.data);
    return (
      <div>
        <ContactList />
        <ContactDetail />
        <AddContactModal />
      </div>
    );
  }
}
  

Комментарии:

1. Взгляните на документы wretch . Это библиотека-оболочка для fetch() , которая ответит на ваш вопрос и, возможно, вам может быть интересно использовать ее для обработки ошибок. 404 не перейдет в fetch() catch, если вы не проверите статус (перед возвратом data.json() и выдачей собственной ошибки

2. Вы пытаетесь распечатать код состояния ошибки / сообщение или что-то в этом роде?

3. @charlietfl ок. Достаточно ли стандартно проверять статус подобным образом и печатать ошибку? Здесь я выполняю сетевой вызов, не так ли? В конечном итоге этот код будет перемещен из компонента в некоторый файл, специфичный для связи с сервером.

4. @wentjun да, это то, что я пытаюсь сделать.

5. ДА… вам нужно создать свою собственную шаблонную передачу ошибок при использовании fetch() . Я предпочитаю, чтобы библиотека делала это за меня. Также упрощает публикацию данных

Ответ №1:

Я попытаюсь перейти шаг за шагом

  1. fetch метод не выдает ошибку, даже если вы получаете коды ответа 4xx или 5xx. Пожалуйста, прочтите о Fetch API внимательно, я полагаю, вы можете найти много интересного, чего вы не знаете об этом.

  2. Вы можете легко проверить статус ответа следующим образом (пожалуйста, прочитайте об Response объекте и его методах / свойствах):

 fetch('/api/wrong_endpoint').then((response) => {
    console.log('status code', response.status)
})
  
  1. Трудно сказать, действительно ли ваш сервер возвращает код 404, потому что я не знаю вашей экспресс-настройки. Если вы установите какой-нибудь запасной обработчик, подобный app.get('*', ...) , то он также может вернуть код успеха 200. Вы можете проверить статус ответа и его тело в DevTools браузера. Но я считаю, что будет лучше, если вы настроите хотя бы свой /api маршрутизатор на возврат ошибки 404, если запрошенный /api/... маршрут не найден.

  2. В чем я действительно уверен, так это в том, что ваш сервер возвращает некоторый HTML-макет в ответе. И вы пытаетесь проанализировать ее как строку JSON через data.json() и, конечно, получаете синтаксическую ошибку, поскольку это не JSON (html-макет начинается с < символа, отсюда и ошибка: SyntaxError: Unexpected token < )

Комментарии:

1. Приятный подробный ответ

Ответ №2:

Как правило, если вы используете fetch API, ошибки 40x и 50x не будут попадать в последующие блоки, поскольку обещание от fetch отклоняет только сетевые ошибки (не ошибки HTTP или что-либо еще). Следовательно, запрос данных с «неправильной» конечной точки будет обработан в первом then блоке.

Я бы рекомендовал вам использовать check your http response body на основе Response.Ok свойства. Успешные ответы будут обработаны в рамках этого условия, тогда как любые другие ответы (ok: false) будут обработаны в другом операторе.

 fetch('/api/wrong_endpoint')
  .then(response => {
    console.log(response) // full response body
    console.log(response.status); // get only the response.status
    if (!response.ok) {
      // http errors 40x and 50x will go into this statement
      // do something to handle it
    } else if (response.ok) {
      // handles status code 200
    }
  })
  .then(
    // ...