iris mvc 中 controller 返回的 error 被静默丢弃,因其仅识别 panic 或 ctx.stopwithstatus() 作为错误信号;需用 ctx.statuscode()+ctx.json()+ctx.stopwithstatus() 组合主动终止请求。

Iris MVC 中 controller 返回的 error 完全被忽略,不触发任何错误处理逻辑——这是统一错误处理失效的根源。
为什么 func(c *Ctrl) Get() (any, error) 里的 error 没用
Iris 的 MVC 层只识别两种错误传播信号:panic 或显式调用 ctx.StopWithStatus()。返回 error 值只是 Go 函数惯用写法,在 Iris 里纯属“静默丢弃”。
- 不加干预时,后续代码照常执行,可能造成空指针、
nilJSON 序列化、甚至返回 200 状态码配脏数据 - 日志不会自动记录,除非你每个方法里手动补
app.Logger().Errorf - 框架根本不会把该
error传给中间件或OnErrorCode处理器
推荐做法:用 ctx.StatusCode() + ctx.JSON() + ctx.StopWithStatus() 组合
这是最可控、调试最直观的方式,避免 recover 泛化捕获掩盖真实崩溃点。
-
ctx.StatusCode(400)必须在ctx.JSON()之前调用,否则响应头状态码仍是 200 -
ctx.StopWithStatus(400)必须紧跟ctx.JSON()后并配return,否则 controller 剩余逻辑仍会执行 - 统一错误结构体(如
BizError)要提前定义且实现Error()方法,方便中间件识别
示例:
if id <h3>备选方案:用 <code>panic(&BizError{})</code> 配 <code>recover</code> 中间件</h3><p>适合已有大量旧代码、想最小改动接入统一格式的场景,但必须严格控制 panic 范围和类型判断。</p>
- 必须用指针 panic:
panic(&BizError{}),不能panic(BizError{}),否则recover无法用类型断言识别 - 中间件里要严格判断
r是否为*BizError,避免把数据库连接崩溃等真异常也吞掉 - panic 后无法再写入 response body(Iris 已关闭 writer),所以只能返回固定 JSON 或重定向
OnErrorCode 只捕获显式设置的状态码,不捕获 panic
app.OnErrorCode(iris.StatusBadRequest, handler) 这类注册,只在 ctx.StatusCode(400) 被调用后、且当前请求尚未结束时触发。它和 panic/recover 是两套独立机制。
- 它不拦截未设置状态码的 panic
- 它不处理 controller 返回的
error - 它的 handler 里可以读取
ctx.Values()传递上下文(比如错误详情),但必须由业务代码主动塞进去
最容易被忽略的一点是:错误结构体的 Code 字段若设计为 40001 这类业务码,需在中间件中自行映射为 HTTP 状态码(如 Code / 100 * 100),OnErrorCode 不会帮你做这层转换。











