Skip to content

feat(openapi): declare endpoint errors without Responsible - #109

Merged
Kilerd merged 1 commit into
mainfrom
fix/explicit-error-responses
Sep 14, 2026
Merged

Kilerd merged 1 commit into
mainfrom
fix/explicit-error-responses

Conversation

@Kilerd

@Kilerd Kilerd commented Sep 14, 2026 •

Copy link
Copy Markdown
Owner

当接口已经通过属性声明了全部错误响应时,Result<Json<User>, ApiError> 仍要求错误枚举实现 Responsible,导致 thiserror + IntoResponse 的常规用法必须再维护一份错误文档。

新增 #[api(errors(...))]:自动推导成功分支,错误分支完全使用接口声明。ApiError 不再需要 Responsible 或 Schematic;实际回传的 body 类型仍需 Schematic,HTTP 错误处理仍由 IntoResponse 决定。

#[api(errors(
    response(status = 404, body = "ErrorBody", description = "User not found"),
    response(status = 409, body = "ErrorBody", description = "User already exists")
))]
async fn create_user() -> Result<Json<User>, ApiError> {
    // ...
}

同一个错误枚举可供不同接口声明不同错误集合。通过一个内部 trait 解析 Result 的成功分支,因此支持 ApiResult<T> 等类型别名,无需按返回类型名称匹配或新增运行时包装。

  • errors(...) 至少声明一个响应,复用现有 response 参数解析和校验。与成功分支同状态的响应按现有合并规则处理。
  • 原有 responses(...) 继续补充/覆盖状态,不会自动免除 trait 要求;同时使用时,它在成功推导和错误合并之后生效。
  • 成功分支的状态、媒体类型、schema 和动态 default 全部保留;只有显式 drop_default 才移除 default。
  • README 提供可编译的 thiserror 示例,迁移文档说明两种属性的语义和处理顺序。

验证覆盖真实 HTTP 响应与文档组装、显式 body 组件收集、多个接口共用错误类型、类型别名、成功分支动态状态、属性覆盖,以及三个编译失败用例(非 Result、缺失成功 schema、旧 responses 仍要求错误契约)。解析校验和成功分支选择各有一个单元测试。

本地验证通过:gotcha 默认和 openapi 完整测试(含 README doctest)、gotcha_core all-features / no-default-features、gotcha_macro 测试、workspace all-features Clippy(-D warnings)、格式和 diff 检查。

GitHub CI:11 项检查全部通过,验证提交 8cb2434d2853adb46d9940318b1be72800c2f14c。

Closes #108

@Kilerd
Kilerd merged commit 3b6296d into main Sep 14, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[api] 显式声明接口错误响应时免除错误类型的 Responsible 要求

1 participant