ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

t3code 依赖的 Effect 4.0:内置 HttpApiError 错误类实现 HttpServerRespondable,可在普通 HTTP 服务端直接返回

t3code 依赖的 Effect 4.0:内置 HttpApiError 错误类实现 HttpServerRespondable,可在普通 HTTP 服务端直接返回 t3code 依赖的 Effect 4.0内置 HttpApiError 错误类实现 HttpServerRespondable可在普通 HTTP 服务端直接返回【免费下载链接】t3code项目地址: https://gitcode.com/GitHub_Trending/t3/t3code本文基于 t3code 仓库内置参考仓库.repos/effect-smol中的 changeset 变更记录eff-701-httpapierror-respondable展开Effect 4.0 让全部内置HttpApiError错误类实现HttpServerRespondable协议使这些错误值不再只能服务于HttpApi声明式框架而是可以直接从普通 HTTP 服务端处理函数中返回由运行时自动渲染为对应的状态码响应。读完本文你能掌握该变更的具体内容、内置错误类与状态码的完整映射、Respondable协议的转换机制以及它在普通 handler 错误中间件中的实际调用链。变更记录本身一段 changeset 描述了什么关联文档是一份标准的 changesets 变更记录位于 .repos/effect-smol/.changeset/pre/eff-701-httpapierror-respondable.md全文只有 frontmatter 与一句变更描述--- effect: patch --- Make all built-in HttpApiError classes implement HttpServerRespondable, so they can be returned directly from plain HTTP server handlers outside of HttpApi.三个要点值得注意变更级别是patch这是补丁级变更说明它被视为行为增强而非破坏性修改——之前这些错误类在HttpApi体系内照常工作之后它们额外获得了被普通服务端识别的能力位置在.changeset/pre/目录changesets 工具在预发布pre-release模式下会把变更记录移入pre/子目录。结合 .repos/effect-smol/packages/effect/package.json 中version为4.0.0-rc.112可以确认该变更属于effect包4.0.0预发布周期内的迭代。t3code 主仓库通过 patches/effect4.0.0-rc.112.patch 锁定的正是同一版本线说明本仓库消费的 Effect 运行时与这份变更记录来自同一发布序列变更目标是HttpApiError内置错误类即400 Bad Request、404 Not Found这类由框架统一提供的状态码错误而不是用户自定义错误。内置错误类全景13 个错误类与状态码映射变更后落地的实现位于 .repos/effect-smol/packages/effect/src/unstable/httpapi/HttpApiError.ts。该模块导出的内置错误类与 HTTP 状态码的完整对应关系如下均可在源文件中直接验证错误类状态码说明ErrorReporter.ignoreBadRequest400请求错误是Unauthorized401未认证是Forbidden403无权限是NotFound404资源不存在是MethodNotAllowed405方法不允许是NotAcceptable406不可接受是RequestTimeout408请求超时是Conflict409冲突是Gone410资源已移除是UnprocessableEntity422语义错误是InternalServerError500服务器内部错误否NotImplemented501未实现否ServiceUnavailable503服务不可用否以NotFound为例源码结构见 HttpApiError.ts是export class NotFound extends Schema.ErrorNotFound(effect/HttpApiError/NotFound)({ _tag: Schema.tag(NotFound) }, { description: NotFound, httpApiStatus: 404 }) { override readonly [ErrorReporter.ignore] true [HttpServerRespondable.symbol]() { return Effect.succeed(notFoundResponse) } }其中notFoundResponse是模块顶部预创建的HttpServerResponse.empty({ status: 404 })HttpApiError.ts#L21-L33 为全部 13 个状态码各缓存了一个空响应实例避免每次渲染都新建对象。从源码结构看每个错误类承担了三重身份Schema.Error派生类携带httpApiStatus元数据可被 OpenAPI 生成、HttpApi端点/中间件的错误声明、反射与生成的客户端所理解——这是变更之前就存在的角色Respondable协议实现者通过实现[HttpServerRespondable.symbol]()方法声明自己应当渲染为哪个响应。这是本次 changeset 新增的能力错误报告策略所有 4xx 类设置了[ErrorReporter.ignore] true表示客户端错误不应触发全局错误上报而InternalServerError、NotImplemented、ServiceUnavailable三个 5xx 类没有该标记意味着直接返回 5xx 错误类时仍会被错误报告器记录。这一区分与运维直觉一致客户端错误是常态服务器错误才需要告警。*NoContent模式变体每个状态码错误类还配套导出了一个NoContent模式变体例如NotFoundNoContentHttpApiError.ts#L152-L154export const NotFoundNoContent NotFound.pipe(HttpApiSchema.asNoContent({ decode: () new NotFound({}) }))asNoContent变体把空响应体固化为契约的一部分解码一个空响应会直接还原为对应错误值。这与Respondable协议方向正好互补——协议解决服务端错误 → HTTP 响应的编码方向NoContent模式解决HTTP 响应 → 错误值的解码方向两端都用同一个类型。HttpApiSchemaError请求/响应解包失败的专用错误同一模块还定义了 HttpApiSchemaError它不是状态码错误而是由 HTTP API 运行时在请求组件解码失败时抛出的错误export class HttpApiSchemaError extends Data.TaggedClass(HttpApiSchemaError){ readonly kind: Params | Headers | Query | Body | Payload | ResponseHeaders readonly cause: Schema.SchemaError } { ... [HttpServerRespondable.symbol]() { return Effect.succeed(badRequestResponse) } }其kind字段记录失败发生的组件位置路径参数、请求头、查询串、请求体、负载或响应头cause保存原始SchemaError它提供static is()类型守卫与static wrap()帮助方法用于把SchemaError提升为带位置的包装错误。渲染上它固定为空的400 Bad Request。该错误类同样实现了Respondable协议与 changeset 中all built-in HttpApiError classes的表述一致。协议机制HttpServerRespondable如何被运行时识别协议本体定义在 .repos/effect-smol/packages/effect/src/unstable/http/HttpServerRespondable.ts核心是一个字符串符号export const symbol ~effect/http/HttpServerRespondable export interface Respondable { [symbol](): Effect.EffectHttpServerResponse, unknown }任何对象只要在自身携带该符号属性即实现[symbol]()方法就被视为可响应值。模块提供三个转换函数构成完整的识别与降级逻辑toResponse严格转换toResponse(self)先检查值是否已经是HttpServerResponse是则直接成功返回否则调用self[symbol]()并Effect.orDie包裹——即协议方法内部抛错会转成 defect。适合在类型系统已经保证值可响应时使用。toResponseOrElse带兜底的宽松转换export const toResponseOrElse (u: unknown, orElse: HttpServerResponse): Effect.EffectHttpServerResponse { if (Response.isHttpServerResponse(u)) { return Effect.succeed(u) } else if (isRespondable(u)) { return Effect.catchCause(u[symbol](), () Effect.succeed(orElse)) } else if (Schema.isSchemaError(u)) { return Effect.succeed(badRequest) } else if (Cause.isNoSuchElementError(u)) { return Effect.succeed(notFound) } return Effect.succeed(orElse) }识别顺序是已构造好的响应 Respondable协议值含变更后加入的全部HttpApiError类SchemaError渲染为 400NoSuchElementError渲染为 404 用户传入的兜底响应。协议值渲染失败时通过Effect.catchCause回退到orElse保证任何情况下都有响应可发。toResponseOrElseDefectdefect 通道的保守转换处理 defect非预期崩溃时只识别响应值与Respondable值两类其余一律回退到orElse——不猜测 defect 应该映射到什么状态码符合未预期错误保守处理的原则。实际调用链普通 handler 的错误为何能被自动渲染这条能力在普通 HTTP 服务端的落点是错误中间件。.repos/effect-smol/packages/effect/src/unstable/http/HttpServerError.ts 中的处理逻辑展示了运行时如何消费该协议// 类型化错误通道 effect Respondable.toResponseOrElse(reason.error, internalServerError) // defect 通道 effect Respondable.toResponseOrElseDefect(reason.defect, internalServerError)两处都把InternalServerError空响应作为兜底参数传入。结合toResponseOrElse的分支逻辑可以还原出普通 handler 中抛错的完整决策表handler 中产生的值最终响应HttpServerResponse实例原样发送NotFound等任一内置HttpApiError值该错误的空状态码响应如 404HttpApiSchemaError空 400SchemaError裸的模式错误空 400NoSuchElementError空 404其他类型化错误 / defect兜底 500这正是 changeset 描述returned directly from plain HTTP server handlers outside ofHttpApi的运行时含义在HttpApp/HttpServer这类普通路由服务中业务代码把new NotFound({})作为错误抛出或返回错误中间件就会经由toResponseOrElse将其渲染为 400/404 等对应响应无需先手工构造HttpServerResponse也无需HttpApi的端点声明机制参与。变更的实际影响与适用前提从本次变更记录与配套源码可以归纳出三点实际影响普通服务端的错误表达成本下降。此前在HttpApi之外的普通 handler 中要让某个状态码返回给客户端通常需要显式构造HttpServerResponse.empty({ status: 404 })之类的响应对象或自定义携带渲染逻辑的错误类型。变更后13 个内置状态码错误类加HttpApiSchemaError均可直接作为错误值使用由中间件统一渲染错误语义与上报语义保持一致。4xx 错误类携带ErrorReporter.ignore标记直接抛Unauthorized不会触发全局错误报告而抛InternalServerError会——即使你是在普通 handler 里正常地返回 5xx协议面向扩展开放。Respondable是一个开放接口任何自定义服务端错误都可以通过实现[HttpServerRespondable.symbol]()获得同样的直接返回即渲染能力HttpApiError内置类只是该协议的首批内置实现者。适用前提需要说明这些模块位于effect包的unstable/http与unstable/httpapi子模块下源文件路径为packages/effect/src/unstable/http...对应effect4.0.0-rc.112预发布版本since标注均为4.0.0即该能力以 4.0 稳定版为基线。t3code 主仓库通过 patches/effect4.0.0-rc.112.patch 与 patches/effect__vitest4.0.0-rc.112.patch 锁定同一版本线引用本仓库时以.repos/effect-smol内实际源码为准。关键路径索引文件内容.repos/effect-smol/.changeset/pre/eff-701-httpapierror-respondable.md本文所依据的 changeset 变更记录.repos/effect-smol/packages/effect/src/unstable/httpapi/HttpApiError.ts13 个内置状态码错误类、*NoContent变体与HttpApiSchemaError的实现.repos/effect-smol/packages/effect/src/unstable/http/HttpServerRespondable.tsRespondable协议符号、isRespondable守卫与三个转换函数.repos/effect-smol/packages/effect/src/unstable/http/HttpServerError.ts错误中间件消费协议的调用点toResponseOrElse/toResponseOrElseDefect.repos/effect-smol/packages/effect/package.jsoneffect包版本4.0.0-rc.112确认变更所属版本线【免费下载链接】t3code项目地址: https://gitcode.com/GitHub_Trending/t3/t3code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表