获取承诺 - 返回 500 内部服务器错误

Bra*_*ube 4 javascript fetch promise

我正在尝试处理 fetch 中的 500 个内部服务器错误。如果发生内部错误,服务器会回复一条消息。我想提取该消息。

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));
      });
  };
Run Code Online (Sandbox Code Playgroud)

我的问题是提取响应的主体会创建一个新的承诺,而我无法拒绝内部承诺的外部承诺。

注 1 触发内部 Promise 的 catch 方法。在 catch 中,我尝试抛出另一个错误,但似乎不起作用。如果我throw new RawException(error)在第二条注释行上,则什么也没有发生,并且then第三条注释行上的方法会触发。如果我在提供的代码中返回一个被拒绝的承诺,那么仍然会触发但 json 是未定义的。

我该怎么做呢?

Bra*_*ube 5

解决方案不是嵌套 promise,而是.then使用内部 promise 的结论来解决/返回外部 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();
}
Run Code Online (Sandbox Code Playgroud)

应该成为

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();
}
Run Code Online (Sandbox Code Playgroud)

如果首选该语法,也可以删除 else 子句。ESLint 抱怨 else 很浪费,但我更喜欢它使代码分支明确的方式。