JavaScript:有没有办法在响应不正常时检测响应是否包含json格式的错误消息

我正在编写一个简单的包装器fetch

async function apiCall(
  endpoint: string,
  {
    data,
    headers: customHeaders,
    ...customConfig
  }: { data?: Object; headers?: Object } = {}
) {
  const config = {
    method: data ? 'POST' : 'GET',
    body: data ? JSON.stringify(data) : undefined,
    headers: {
      'content-type': data ? 'application/json' : undefined,
      ...customHeaders,
    },
    ...customConfig,
  }

  return fetch(endpoint, config as any).then(async (response) => {
    if (response.ok) {
      const json = await response.json() // 
      return json
    } else {
    //   what if `response` contains error messages in json format?
      return Promise.reject(new Error('Unknown Error'))
    }
  })
}

它工作正常。问题出在这个片段上

 return fetch(endpoint, config as any).then(async (response) => {
    if (response.ok) {
      const json = await response.json()
      return json
    } else {
    //   what if `response` contains error messages in json format?
      return Promise.reject(new Error('Unknown Error'))
    }
  })

如果响应不正常,它会拒绝一个通用的Error. 这是因为默认情况下,window.fetch只有在实际网络请求失败时才会拒绝承诺。但问题是,即使response不正常,它仍然可能会出现json格式错误消息。这取决于后端实现细节,但有时您可以通过response.json(). 现在这个用例没有包含在我构建的包装器中。

所以我想知道我将如何能够解释这一点?我想你可以做类似的事情

fetch(endpoint, config as any).then(async (response) => {
      if (response.ok) {
        const json = await response.json()
        return json
      } else {
          try {
            const json = await response.json()
            return Promise.reject(json)
          } catch {
            return Promise.reject(new Error('Unknown Error'))
          }
      }
    })

但我想知道是否有一些更优雅的方法来做到这一点?

最后,我非常了解像 Axios 这样的库。我建造这个部分是为了满足我的求知欲。

顺便说一句,一个稍微不相关的问题,但我想知道这两个是否等效

 if (response.ok) {
        const json = await response.json()
        return json
      }
 if (response.ok) {
        return response.json()
      }

有人将我的问题标记为与此问题重复。事实上,它们并不相同。我没有做出与该问题相同的假设,即 API 调用在成功和失败时都返回 JSON 数据。我的问题是在我们不能做出这样的假设的情况下,我们究竟应该怎么做。

回答

响应不是ok不会阻止您将其主体作为 JSON 使用,因此您的最后一个片段确实应该如何处理。

现在您要求“更优雅”的东西,它可能不会更优雅,但编写相同内容的冗余方式将是:

fetch(endpoint, config as any).then(async (response) => {
  if (response.ok) {
    return response.json(); // there is no need to await the return value
  }
  else {
    const err_message = await response.json() // either we have a message
      .catch( () => new Error( "Unknown Error" ) ); // or we make one
    return Promise.reject( err_message );
  }
})

关于最后一个问题,是的,两者是等价的,await版本通过微任务队列再进行一次往返并使您的代码更长一些,但对于所有重要的事情,我们可以说它们是相同的。


以上是JavaScript:有没有办法在响应不正常时检测响应是否包含json格式的错误消息的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>