状态处理器
介绍
状态处理器 是类似于控制器的 组件,实现了一个常规处理器,如果 响应体为空 但已设置状态码,则在请求生命周期的 最终化 步骤中执行。状态处理器主要用于为用户或服务器错误实现自定义行为(分别对应 400
和 500
状态码)。简而言之,状态处理器是一种集中处理一个或多个响应状态码的方式。
Goyave 自带三个内置状态处理器,默认定义如下:
goyave.PanicStatusHandler
:用于错误和 panic(500
)goyave.ErrorStatusHandler
:用于非成功码(400
码、501
+ 码)goyave.ValidationStatusHandler
:用于422 Unprocessable Entity
(验证错误)
panic 和错误处理器返回对应状态码的简单错误消息。
json
{
"error": "Not Found"
}
INFO
500
状态处理器是一个例外:即使在写入后发生错误或 panic,它仍将被执行。
实现状态处理器
状态处理器实现在 http/controller/status
包中。如果您的状态处理器相当大,可以将它们拆分成多个文件,否则您可以将它们全部实现在一个 status.go
文件中。
状态处理器是必须实现 goyave.StatusHandler
接口的结构体。该接口要求您的结构体是一个 goyave.Component
,并实现一个 Handle(*Response, *Request)
方法。
示例:
go
package status
import (
"goyave.dev/goyave/v5"
)
type CustomHandler struct {
goyave.Component
}
func (*CustomHandler) Handle(response *goyave.Response, request *goyave.Request) {
message := map[string]string{
"message": request.Lang.Get("customStatusHandlerResponse"),
}
response.JSON(response.GetStatus(), message)
}
WARNING
状态处理器在处理程序栈 外部 执行,因为它们是 最终化 步骤的一部分。因此,它们 不受 恢复中间件保护。请特别注意构建您的状态处理器,以确保它们绝不会 panic
。
注意
如果您的状态处理器未向响应体写入任何内容,状态码 不会 更改为 204 No Content
。
扩展默认状态处理器
您可以通过 组合 默认状态处理器来扩展它们。这在您希望保留默认行为并仅添加一些自定义操作时非常有用。例如,如果您想使用错误跟踪服务:
go
type ErrorHandler struct {
goyave.PanicStatusHandler
}
func (h *ErrorHandler) Handle(response *goyave.Response, request *goyave.Request) {
errortracker.Notify(response.GetError())
h.PanicStatusHandler.Handle(response, request)
}
注册状态处理器
状态处理器在 路由器 中注册。
go
func Register(_ *goyave.Server, router *goyave.Router) {
router.StatusHandler(&status.ErrorHandler{}, http.StatusInternalServerError)
router.StatusHandler(&status.CustomHandler{}, 401, 402, 403)
//...
}
TIP
状态处理器在子路由器中作为克隆继承。修改子路由器的状态处理器不会修改其父级。这意味着您可以为某些路由组定义不同的状态处理器,并且您应该在子路由器之前注册您的状态处理器。