@keq-request/exception
用于抛出/捕获异常的 Middleware。并且可控制抛出的异常是否触发 retry。
安装
- npm
- pnpm
- yarn
使用方法
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.fatal | false | 设置为 true 可以终止重试机制 |
| options.response | - | 关联的 Response 对象 |
Middleware
validateStatusCode
验证 Response 的 status,并抛出对应的 RequestException:
status在200-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",真正的原因(如 ECONNREFUSED、ENOTFOUND、ETIMEDOUT)藏在 .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())