iris 框架中,ctx.statuscode() 仅修改响应状态码而不触发 onerrorcode;只有未匹配路由或显式调用 ctx.next() 后的状态码才会执行对应错误处理器,静态资源 404 和中间件 panic 默认不走该机制。

直接改状态码用 ctx.StatusCode(),但要注意它只影响响应头,不自动触发错误处理逻辑;想让 404/500 走自定义页面,必须配合 app.OnErrorCode()。
ctx.StatusCode() 只改状态码,不走 OnErrorCode
调用 ctx.StatusCode(iris.StatusNotFound) 后,响应头里确实是 404,但不会自动跳转到你用 app.OnErrorCode(iris.StatusNotFound, ...) 注册的处理器——除非这个 404 是由 Iris 内部未匹配路由触发的,或者你手动调用了 ctx.Next() 让流程继续往下走。
- 常见错误现象:在某个路由 handler 里写
ctx.StatusCode(404); ctx.WriteString("not found"),结果页面显示文字但没进OnErrorCode函数 - 原因:Iris 的
OnErrorCode是“错误码拦截器”,不是“状态码监听器”;它只对未被处理的、框架级抛出的错误码生效 - 如果你真想强制走自定义错误页,得手动调用
ctx.StopExecution()+ctx.Next(),或者干脆在 handler 里直接复用OnErrorCode对应的逻辑
OnErrorCode 绑定后,哪些情况会触发?
app.OnErrorCode(iris.StatusNotFound, notFoundHandler) 注册后,以下两种场景才会执行 notFoundHandler:
- 用户访问了一个完全没注册的路径(比如注册了
/api/users,却请求/api/posts) - 你在某个 handler 里调用
ctx.StatusCode(iris.StatusNotFound)并紧接着调用ctx.Next()(注意:不是ctx.StopExecution())
其他情况如中间件 panic、手动 panic(errors.New("xxx")),默认不会触发 OnErrorCode,得靠 app.UseRouter() 或自定义 recover 中间件捕获。
静态资源 404 不走 OnErrorCode 是正常行为
当你配置了 app.Static("/static", "./dist"),但请求 /static/missing.js 返回 404 时,OnErrorCode 不会执行——因为 Iris 的静态文件服务是独立于主路由树的,它自己处理 404,不经过通用错误码分发机制。
- 验证方式:在
OnErrorCode里加日志,访问不存在的 API 路径能看到输出,访问不存在的静态资源则看不到 - 解决办法:要么把静态资源路径收口到一个统一 handler(用
app.Get("/static/*file", staticHandler)),要么在staticHandler里自己判断文件是否存在并手动调用ctx.StatusCode()+ctx.Next() - 注意:别依赖
os.Stat每次都查磁盘,性能差;可以用http.FileServer包装后加一层 wrapper,或预加载文件列表
修改 500 错误页要小心中间件顺序
如果你在中间件里 panic,又希望 app.OnErrorCode(iris.StatusInternalServerError, ...) 生效,必须确保该中间件在 app.UseRouter() 之前注册,否则 panic 会被更外层的 HTTP server 捕获,根本进不到 Iris 的错误码系统。
- 正确顺序:
app.Use(recoverMiddleware)→app.UseRouter()→app.OnErrorCode(...) - 错误顺序:
app.OnErrorCode(...)放最前,然后app.Use(...),panic 仍会直接返回默认 500 页面 - recoverMiddleware 示例里别忘了调用
ctx.StatusCode(500)和ctx.Next(),否则OnErrorCode还是不触发
真正容易被忽略的是:Iris 的错误码处理不是全局钩子,它只对“路由匹配失败”和“显式调用 Next() 后的状态码”起作用。静态资源、中间件 panic、TLS 握手失败这些都不归它管——得各找各的解法。











