1.1.0 • Published 8 months ago

@hcfy/fetch-error v1.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

FetchError

动机

在使用 Fetch API 时,错误处理有点棘手:

  • 服务器返回非 200 的 HTTP 响应码时,fetch 不会抛错,需要我们自己手动生成一个错误对象
  • 出现网络错误时,fetch 抛出的错误没有特征,无法准确分辨一个错误是 fetch 抛出的还是其它代码抛出的

为此,这个模块定义了统一的 FetchError。

如何使用

import FetchError, { isFetchError } from '@hcfy/fetch-error'

function myFetch() {
  const request = { url: '...', method: 'POST' }
  return fetch(request.url, request).then(
    (response) => {
      if (!response.ok) {
        throw new FetchError(response, request)
      }
      return response
    },
    (e) => {
      return Promise.reject(new FetchError(e, request))
    }
  )
}

myFetch().then(
  (response) => {
    // 代码执行到这里,response.ok 一定是 true
  },
  (error) => {
    if (isFetchError(error)) {
      // 这是 fetch 抛出的错
      // 可以访问 request
      console.log(error.request)

      if (error.response) {
        // 这是由于 response.ok 不是 true 而抛的错
      } else {
        // 这是 fetch 直接抛的错,即网络问题导致请求没有送达服务器、或者被用户中断了。
        // 可以通过 error.cause 拿到具体错误。
        const originError = error.cause
      }
    } else {
      // 这是其它错误
    }
  }
)

注意事项

FetchError 依赖全局环境中的 Response 来判断第一个参数是 response 还是引起报错的 cause,所以:

  1. 你需要确保全局环境中有 Response
  2. 你需要确保你的 fetch 函数返回的 response 是全局环境中的 Response 的实例

举个例子,Node.js v18 中在全局环境中已有 Response,但如果你是用 node-fetch 发起的请求,而由于 node-fetch 的 response 并不是 Node.js v18 中 Response 的实例,这就会导致 FetchError 将它识别为错误 cause。这种情况下,你需要将全局环境中的 Response 修改为 node-fetch 的 Response。