fetch promises - return 500 internals server error

試著忘記壹切 提交于 2020-01-14 04:18:10

问题


I am trying to handle 500 internal server errors inside fetch. If an internal error occurs, the server responds with a message. I want to extract that message.

const req = new Request(url, {
      method: node.method,
      mode: 'cors',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body),
    });
    fetch(req)
      .then((response) => {
        if (response.status === 500) {
          // res.json extracts the body from the response as a promise, chain
          // .then on it and throw an error to be caught in the lower catch.
          response.json()
          .then((json) => {
            const { message, stackTrace } = json;
            throw new ServerException(message, stackTrace); // note 1
          })
          .catch((error) => {
            return Promise.reject(RawException(error)); // note 2
          });
        } else {
          return response.json();
        }
      })
      .then((json) => { // note 3
        dispatch(stopLoading());
        dispatch(recieveResponse(typeOfRequest, json));
      })
      .catch((e) => {
        dispatch(stopLoading());
        dispatch(responseError());
        dispatch(showError(e.message));
      });
  };

My issue is that extracting the body of the response creates a new promise, and I am unable to reject the outer promise from the inner one.

Note 1 triggers the catch method of the inner promise. Inside catch, I have tried throwing another error but it doesn't seem to work. If I throw new RawException(error) on the second noted line, nothing happens and the then method on the third noted line triggers. If I return a rejected promise as I have in the code provided, then still triggers but json is undefined.

How do I do this?


回答1:


The solution is not to nest promises, but to resolve/return the .then of the outer promise with the conclusion of the inner promise.

if (response.status === 500) {
  response.json()   // response.json returns a promise, we chose to do nothing with its
  .then((json) => { // conclusion
    const { message, stackTrace } = json;
    throw new ServerException(message, stackTrace); // note 1
  })
  .catch((error) => {
    return Promise.reject(RawException(error)); // note 2
  });
} else {
  return response.json();
}

Should become

if (response.status === 500) {
  return response.json() // return the result of the inner promise, which is an error
  .then((json) => {
    const { message, stackTrace } = json;
    throw new ServerException(message, stackTrace);
  });
} else {
  return response.json();
}

The else clause can be removed as well if that syntax is preferred. ESLint complains about the else being wasteful, but I perfer the way it makes the code's branching explicit.



来源:https://stackoverflow.com/questions/41729602/fetch-promises-return-500-internals-server-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!