这里https://github.com/astaxie/build-web-application-with-golang/blob/master/en/11.1.md描述了如何根据http包增强自定义路由器和自定义错误类型的错误处理。
type appError struct {
Error error
Message string
Code int
}
type appHandler func(http.ResponseWriter, *http.Request) *appError
// custom handler catching errors
func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if e := fn(w, r); e != nil { // e is *appError, not os.Error.
c := appengine.NewContext(r)
c.Errorf("%v", e.Error)
http.Error(w, e.Message, e.Code)
}
}
// fetch data or return *appError
func viewRecord(w http.ResponseWriter, r *http.Request) *appError {
c := appengine.NewContext(r)
key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
record := new(Record)
if err := datastore.Get(c, key, record); err != nil {
return &appError{err, "Record not found", 404}
}
if err := viewTemplate.Execute(w, record); err != nil {
return &appError{err, "Can't display record", 500}
}
return nil
}
目的是让所有处理程序在出现错误时返回* appError并将其写入路由器的响应中,因此无需直接在{{1}的代码中调用c.JSON(500,err) }}
如何对Gin进行同样的操作?
答案 0 :(得分:3)
Here @manucorporat gin-developer说:
我们鼓励开发人员使用中间件来处理错误响应,以便他们可以从正常的流逻辑中拆分错误逻辑。
在Gin中实现集中式错误处理你应该使用。使用(中间件)并在路径处理程序的代码中使用gin.Context.Error()将错误信息附加到请求上下文。中间件知道gin.Context.Errors,在这里你可以在gin.Context.Next()
之后阅读它们并按照你的意愿处理。
以下代码。
处理Gin中间件时出错:
//
// APP error definition
//
type appError struct {
Code int `json:"code"`
Message string `json:"message"`
}
//
// Middleware Error Handler in server package
//
func JSONAppErrorReporter() gin.HandlerFunc {
return jsonAppErrorReporterT(gin.ErrorTypeAny)
}
func jsonAppErrorReporterT(errType gin.ErrorType) gin.HandlerFunc {
return func(c *gin.Context) {
c.Next()
detectedErrors := c.Errors.ByType(errType)
log.Println("Handle APP error")
if len(detectedErrors) > 0 {
err := detectedErrors[0].Err
var parsedError *appError
switch err.(type) {
case *appError:
parsedError = err.(*appError )
default:
parsedError = &appError{
code: http.StatusInternalServerError,
message: "Internal Server Error"
}
}
// Put the error into response
c.IndentedJSON(parsedError.Code, parsedError)
c.Abort()
// or c.AbortWithStatusJSON(parsedError.Code, parsedError)
return
}
}
}
//
// Report Error in app
//
func fetchSingleHostGroup(c *gin.Context) {
hostgroupID := c.Param("id")
hostGroupRes, err := getHostGroupResource(hostgroupID)
if err != nil {
// put the Error to gin.Context.Errors
c.Error(err)
return
}
// return data of OK
c.JSON(http.StatusOK, *hostGroupRes)
}
//
// Server setup
//
func main() {
router := gin.Default()
router.Use(JSONAppErrorReporter())
router.GET("/hostgroups/:id", fetchSingleHostGroup)
router.Run(":3000")
}
可以在以下网址找到另一个错误处理提示: