Skip to main content

@keq-request/exception

用于抛出/捕获异常的 Middleware。并且可控制抛出的异常是否触发 retry

安装

使用方法

import { request, RequestException } from "keq"
import {
  throwException,
  catchException,
} from "@keq-request/exception"

request
  .use(
    catchException((err) => {
      if (err instanceof RequestException && err.statusCode === 401) {
        context.redirect("/login")
        return
      }

      throw err
    })
  )

  // throwException 的回调函数必然在`await next()`后运行
  // 可以在回调函数中尝试获取 Response
  .use(
    throwException(async (ctx) => {
      if (ctx.response && ctx.response.status >= 400) {
        const body = await ctx.response.json()
        throw new RequestException(ctx.response.status, body.message)
      }
    })
  )

RequestException(statusCode[, errorMessage[, options]])

参数默认值描述
statusCode-HTTP 状态码
message''错误信息
options.fatalfalse设置为 true 可以终止重试机制
options.response-关联的 Response 对象

Middleware

validateStatusCode

验证 Responsestatus,并抛出对应的 RequestException

  • status200-399 范围内时,不抛出异常
  • status = 400 时,抛出 BadRequestException(statusText)
  • status = 401 时,抛出 UnauthorizedException(statusText)
  • status = 403 时,抛出 ForbiddenException(statusText)
  • status = 404 时,抛出 NotFoundException(statusText)
  • status = 405 时,抛出 MethodNotAllowedException(statusText)
  • status = 406 时,抛出 NotAcceptableException(statusText)
  • status = 407 时,抛出 ProxyAuthenticationRequiredException(statusText)
  • status = 408 时,抛出 RequestTimeoutException(statusText)
  • status = 409 时,抛出 ConflictException(statusText)
  • status = 412 时,抛出 PreconditionFailedException(statusText)
  • status = 413 时,抛出 ContentTooLargeException(statusText)
  • status = 414 时,抛出 UriTooLongException(statusText)
  • status = 415 时,抛出 UnsupportedMediaTypeException(statusText)
  • status = 418 时,抛出 ImATeapotException(statusText)
  • status = 429 时,抛出 TooManyRequestsException(statusText)
  • status 为其他 400-499 的数值时,抛出 RequestException(status, statusText, { fatal: true })
  • status = 500 时,抛出 InternalServerErrorException(statusText)
  • status = 501 时,抛出 NotImplementedException(statusText)
  • status = 502 时,抛出 BadGatewayException(statusText)
  • status = 503 时,抛出 ServiceUnavailableException(statusText)
  • status = 504 时,抛出 GatewayTimeoutException(statusText)
  • status 为其他 500-599 的数值时,抛出 RequestException(status, statusText, { fatal: false })

示例

import { request } from "keq"
import { validateStatusCode } from "@keq-request/exception"

request.use(validateStatusCode())

clarifyFetchFailed

Node.js 原生 fetch 在网络错误时抛出 TypeError,其 message 仅为 "fetch failed",真正的原因(如 ECONNREFUSEDENOTFOUNDETIMEDOUT)藏在 .cause 属性中。clarifyFetchFailed 中间件会将 .cause 链中的信息展开拼接到错误的 message 中,使日志和错误信息更具可读性。

效果

// Before
TypeError: fetch failed

// After
TypeError: fetch failed: connect ECONNREFUSED 127.0.0.1:3000

示例

import { request } from "keq"
import { clarifyFetchFailed } from "@keq-request/exception"

request.use(clarifyFetchFailed())