onerrorcode仅捕获路由未匹配或panic未recover的错误,不处理mvc方法不存在或签名错误导致的404;mvc层404需在beforeactivation显式绑定路径,500需在中间件中类型断言bizerror并正确响应。

Mvc中404和500不会自动触发OnErrorCode
你在MVC控制器里写了GetSomething方法,但访问不存在的路径(比如/api/xxx)时,app.OnErrorCode(iris.StatusNotFound, ...)根本没执行——因为Iris的OnErrorCode只对**未匹配到任何路由**或**panic未被recover**的情况生效,而MVC层的404通常发生在路由已匹配、但Controller方法不存在(如GetXXX拼错)或方法签名不合法时,此时框架内部会直接返回404,绕过你注册的全局错误处理器。
换句话说:OnErrorCode管的是“路由层404”,不是“MVC方法层404”。
捕获MVC方法不存在导致的404
当用户请求/user/123,你注册了UserController,但里面没写GetByID方法(或写成了GetById),Iris默认返回空白或404 Not Found纯文本,且不进你的OnErrorCode函数。
- 必须在
BeforeActivation里显式注册所有可能路径,避免“方法名拼错却静默404” - 用
b.Handle("GET", "/user/{id}", "GetByID")绑定字符串方法名,比依赖命名约定更可靠 - 在
BeforeActivation里加日志:fmt.Printf("registering GET /user/{id} → GetByID\n"),上线前人工核对注册表 - 如果仍要兜底,可在
AfterActivation里遍历a.GetRoutes(),检查是否漏注册关键路径
让500在MVC中走统一panic恢复
MVC控制器里panic会被Iris捕获并转成500,但前提是没被中间件提前recover。如果你在全局中间件里写了defer func(){recover()}()又没做类型判断,就可能吞掉*BizError导致500页面不显示。
- panic前必须确保是
*BizError或明确可识别的错误类型,否则recover()拿到interface{}无法区分业务错误和系统崩溃 - 在全局
Use中间件里,recover()后先做类型断言:if be, ok := r.(*BizError); ok { ctx.StatusCode(be.Code) ... } - 不要在Controller方法里用
return err指望框架处理——Iris MVC不看返回值里的error,必须panic或ctx.StopWithStatus -
StopWithStatus后必须return,否则方法继续执行,可能造成重复写库或panic二次触发
静态文件404和MVC 404别混在一起
你配了app.StaticWeb("/static", "./public"),但访问/static/missing.css也进了MVC的404逻辑?这是路径注册顺序问题。
Iris按注册顺序匹配路由,如果StaticWeb写在mvc.New(app.Party("/"))之后,所有/static/*请求会先被MVC的泛匹配路由(比如/static/{path *wildcard})吃掉,根本到不了静态服务。
-
StaticWeb和FileServer必须放在mvc.New和app.Get等所有动态路由之前 - 验证方式:启动后curl -I http://localhost:8080/static/missing.css,状态码应为
404且响应头含Content-Type: text/plain(StaticWeb默认行为),而不是HTML - 如果需要自定义静态资源404,得单独为
/static/*写一个handler,里面调ctx.StatusCode(404)再渲染模板,不能依赖OnErrorCode











