错误响应差异

HTTP status 与 JSON status 是两层。当前响应没有公共顶层 messagelocalizedError 也不保证非空。接口页必须链接实际适用的出口,不能按服务名或 @PreAuthorize 猜测。本页是全站错误出口的唯一正本;响应信封结构的通则演示见 API 域规范页(data-servicedevice-service),端点级错误事实以清单层与 Swagger 为准。

Security filter、entry point:认证拒绝

当前行为
触发 JWT 或认证异常,或未认证访问最终进入 entry point
HTTP / body status 200 / 1000
字段 error 为认证常量;不本地化;不应有业务 extraData.message
接入影响 HTTP 2xx 不代表认证成功;仍须按实际入口确认

Security denied handler:权限拒绝

当前行为
触发 权限失败最终交给 Security denied handler
HTTP / body status 200 / 1001
字段 error 为权限常量;不本地化;不应有业务 extraData.message
接入影响 传输状态为 2xx 时仍须解析业务状态

main ExceptionAdvice:认证与权限异常

当前行为
触发 MVC 边界捕获认证或权限异常
HTTP / body status 认证为 401 / 1000;权限为 403 / 1001
字段 error 为相应常量;尝试填充 localizedError,但可能为空
接入影响 与 Security filter 同一失败族的传输状态可能不同

device ExceptionAdvice:认证与权限异常

当前行为
触发 MVC 边界捕获认证或权限异常
HTTP / body status 200 / 1000200 / 1001
字段 不填本地化;不应有业务 extraData.message
接入影响 不可用 main Advice 的 HTTP 状态替代 device 行为

两服务 Advice:业务拒绝

当前行为
触发 ApiException,包括 Security filter 委托 Advice 的路径
HTTP / body status 200 / ex.status;默认,仅显式 null 时回退
字段 error=ex.getMessage,保留 extraData;main 尝试本地化,device 不填
接入影响 不能因异常发生在 filter 就把它归为认证失败

两服务 Advice:请求解析与校验

当前行为
触发 body 转换、参数绑定、Bean Validation 或 constraint violation
HTTP / body status 400 / 1002、 或
字段 安全摘要;校验错误可聚合;main 尝试本地化
接入影响 保留响应 body 以支持字段提示,不能只展示 HTTP 400

两服务 Advice:路由与媒体类型

当前行为
触发 路径不存在、HTTP method 不支持或 Content-Type 不支持
HTTP / body status 404 / 1008405 / 1006415 / 1007
字段 固定协议摘要;main 尝试本地化
接入影响 不能用单一“非 200 即失败”规则抹平 body status 差异

Security filter 或 Advice:未处理技术异常

当前行为
触发 未处理技术异常
HTTP / body status 500 / 500
字段 error 为安全摘要;main Advice 尝试本地化,main filter 与 device 不填
接入影响 客户端需同时处理可解析业务 body 与非 JSON 网关失败

Agent API(/agent-api/v1/**):签名失败与脚本失败

当前行为
触发 query/header 签名缺失、过期、未来时间或 token 不匹配;或 handler 返回 AppError
HTTP / body status 签名失败 401 / 401;内部失败 500 / 500(axum 按 envelope status 回写 HTTP status,common/api.rs:103-110
字段 Rust ApiResult 信封:error 为固定英文摘要("missing token or time""time window expired""invalid token""backup_failed: …" 等);path 填充请求路径;extra_data=null(serde 无 rename,wire 为 snake_case,与 Java 信封的 extraData 不同)
接入影响 Agent 不接入中心账号体系,无 1000/1001 业务码族;能构造签名的客户端即可调用

Meilisearch 代理:上游错误透传

当前行为
触发 上游 Meilisearch 返回非 2xx(RestClientResponseException),或代理自身异常
HTTP / body status 经 main Advice 业务拒绝出口:HTTP,body status = 上游 HTTP 状态码(显式 setStatus);代理自身异常为 200 / 500
字段 error="Meilisearch proxy error: {上游消息}""Proxy error: …";注意检索成功响应不走 {status,data} 信封(原样字节流)
接入影响 status 值域是上游 HTTP 码(404/400 等),不是 1000/422 族业务码;须按上游 API 语义解释

以上为当前实现差异,不是未来统一目标。无效或缺失 token 是否立即得到 取决于过滤链和白名单,不能一概而论。

依据

适用后端基线:源码归纳 @ 2026-09-14(Agent 信封与 Meilisearch 代理两行由整合票 20 于 2026-09-12 复核)。

出口 源码定位
认证拒绝权限拒绝 main config/SecurityConfig.usernamePasswordAuthenticationFilter:433–449、、;device 同名符号 、
main Advice main controller/ExceptionAdvice.authenticationExceptionHandler:72–93
device Advice device controller/ExceptionAdvice 认证/权限 handlers
业务拒绝 main ExceptionAdvice.apiExceptionHandler:232–236、filter;device Advice 、filter
请求校验路由与媒体类型 main;device
技术异常 main filter 、Advice;device filter 、Advice
Agent 签名与信封 es-center-server-agent config/app.rs:150–195(401 出口)、common/api.rs:26–110(信封与 HTTP status 回写)、common/app_error.rs:39–48(AppError→信封)
Meilisearch 代理透传 保留上游 HTTP 状态码(经统一异常出口),经 main Advice 业务拒绝出口

认证和权限的状态码语义为源码归纳结论。每个操作仍须从自身入口链确认实际落到哪个出口。Agent 信封差异由票 16 四页与整合票 20 复核后合并;Meilisearch 代理出口依据票 16 枚举日志检索索引 正本。