Echo框架自定义HTTPErrorHandler无法使用CustomContext问题咨询
哥们,这个问题我之前踩过同款坑,咱们一步步把它掰扯明白:
先看你贴的这段配置代码:
e.Use(func(h echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { cc := c.(*CustomContext) return h(cc) } }) e.HTTPErrorHandler = func(err error, c echo.Context) { cc := c.(*CustomContext) }
你遇到的矛盾点很明确:主动调用c.Error(echo.NewHTTPError(http.StatusUnauthorized, "error"))时一切正常,但访问未注册页面触发404时就直接panic,报错echo.Context is *echo.context, not *CustomContext。
核心原因:中间件的执行范围有限
你用e.Use()注册的中间件,只会在匹配到已定义路由的请求流程中执行。而当请求是未注册的路由时,Echo根本不会走到你这个中间件逻辑里——它会直接触发框架内置的404处理流程,这时候传递给HTTPErrorHandler的Context还是框架原生的*echo.context,你强行把它转换成*CustomContext自然会触发类型断言panic。
至于主动调用c.Error()时正常的原因也很直观:那是在你自己的路由处理函数里,请求已经经过了中间件的转换,Context已经是*CustomContext了,类型转换当然不会出问题。
解决办法
这里有两种靠谱的处理方式,按需选就行:
方式一:自定义NotFoundHandler,提前转换Context
直接替换Echo的默认404处理器,在里面先把原生Context转换成你的CustomContext,再触发错误处理:
e.NotFoundHandler = func(c echo.Context) error { // 将默认Context包装成自定义的CustomContext cc := &CustomContext{Context: c} // 抛出自定义404错误,交给你的HTTPErrorHandler处理 return cc.Error(echo.NewHTTPError(http.StatusNotFound, "请求的页面不存在")) }
方式二:用Pre中间件全局转换Context
如果希望所有请求(不管有没有匹配到路由)都先经过Context转换,可以把转换逻辑放到Pre中间件里——它会在路由匹配之前就执行,覆盖所有请求场景:
e.Pre(func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { // 把默认Context转换成自定义的CustomContext cc := &CustomContext{Context: c} return next(cc) } })
这样不管是正常路由请求还是404请求,传递到后续逻辑(包括HTTPErrorHandler)的都是*CustomContext,类型转换就不会再panic了。
内容的提问来源于stack exchange,提问作者Lansi

