Как получить ответ об ошибке axios INTO метод перехвата саги - PullRequest
0 голосов
/ 14 января 2019

С аксиосами код:

export const createBlaBla = (payload) => {
  return axios.post('/some-url', payload)
    .then(response => response)
    .catch(err => err);
}

А потом я использую это с Редукс-сагой вот так:

function* createBlaBlaFlow(action) {
  try {
    const response = yield call(createBlaBla, action.payload);
    if (response) {
      yield put({
        type: CREATE_BLA_BLA_SUCCESS
      });
    }
  } catch (err) {
    // I need the error data here ..
    yield put({
      type: CREATE_BLA_BLA_FAILURE,
      payload: 'failed to create bla-bla'
    });
  }
}

В случае какой-либо ошибки на сервере - например, неверные данные, отправленные на сервер - возвращают ответ 400 с некоторыми данными:

{
  "code":"ERR-1000",
  "message":"Validation failed because ..."
  "method":"POST",
  "errorDetails":"..."
}

Но я не получаю эти полезные данные в операторе catch внутри саги. Я могу console.log () данные в операторе axios catch, также я могу получить их внутри оператора try в саге, но они никогда не поступят в catch.

Вероятно, мне нужно сделать что-то еще? ... Или сервер не должен возвращать 400 ответов в этом случае?

Ответы [ 2 ]

0 голосов
/ 29 мая 2019

В своем вызове API вы можете сделать следующее:

const someAPICall = (action) => {
  return axios.put(`some/path/to/api`, data, {
    withCredentials: true,
    validateStatus: (status) => {
      return (status == 200 || status === 403);
    }
  });
};

Обратите внимание на часть validateStatus() - таким образом, когда axios встретит ответ 200 или 403, он не выдаст ошибку и вы сможете обработать ответ после

const response = yield call(someAPICall, action);
if (response.status === 200) {
  // Proceed further
} else if (response.status === 403) {
  // Inform user about error
} else {
  ...
}
0 голосов
/ 22 января 2019

Итак, я придумал два решения этой проблемы.

===

Первый - очень обходной путь дампа, но на самом деле это может быть полезно в некоторых конкретных случаях.

В саге, прямо перед тем, как мы вызываем функцию с вызовом axios внутри, у нас есть переменная для ошибок и обратный вызов, который устанавливает эту переменную:

let errorResponseData = {};
const errorCallback = (usefulErrorData) => {
    errorResponseData = usefulErrorData;
};

Тогда - в методе axios мы имеем это:

export const createBlaBla = (payload, errCallback) => {
    return axios.post('/some-url', payload)
        .then(response => response)
        .catch(err => {
            if (err && err.response.data && typeof errCallback === 'function') {
                errCallback(err.response.data);
            }
            return err;
        });
}

Таким образом, когда мы делаем запрос и сервер возвращает ошибки - мы будем вызывать обратный вызов и сообщать об ошибках от сервера. Таким образом, в саге, у нас есть ошибки в переменной, и мы можем использовать ее по своему желанию.

===

Однако другое решение пришло ко мне с другого форума.

У меня проблема в том, что в методе с вызовом axios у меня есть catch, что означает, что ошибки не будут пузыриться в генераторе. Так что - если мы изменим метод с помощью вызова axios, как это:

export const createBlaBla = (payload) => {
  return axios.post('/some-url', payload)
}

Тогда в выражении catch в саге мы получим реальную ошибку бэкэнда.

Надеюсь, это поможет кому-то еще:)

...