更好的错误处理 [英] Better error handling

查看:94
本文介绍了更好的错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此处 https:// github .com / astaxie / build-web-application-with-golang / blob / master / zh / 11.1.md 描述了如何根据http包使用自定义路由器和自定义错误类型来增强错误处理能力。

Here https://github.com/astaxie/build-web-application-with-golang/blob/master/en/11.1.md described how to enhance error handling with custom router and custom error type according to http package.

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并将其写入路由器的响应中,因此没有必要直接在 viewRecord 的代码中调用c.JSON(500,err)。

The aim is to make all the handlers returning *appError in case of error and write it into response in the router, so there is no need to call c.JSON(500, err) directly in the code of viewRecord.

如何执行相同操作与

推荐答案

此处 @manucorporat gin-developer说:

Here @manucorporat gin-developer say:


我们鼓励开发人员使用中间件来处理错误响应,以便他们可以将错误逻辑与常规流逻辑分开

We encourage developers to use a middleware to handle the error responses, so they can split the error logic, from the normal flow logic.

在Gin中实现集中式错误处理,您应该使用.Middleware并在路径h中安德勒的代码使用gin.Context.Error()将错误信息附加到请求上下文。中间件知道gin.Context.Errors,您可以在 gin.Context.Next()之后阅读并处理它们。

In the Gin to implement centralized error handling your should .Use(Middleware) and in the path handler's code use gin.Context.Error() to attach an error info to the request context. The Middleware is aware of gin.Context.Errors and here you can read them and process as you wish after gin.Context.Next().

下面的代码。

错误处理Gin中间件:

Error handling Gin Middleware:

//
// 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")
}

另一个错误处理思路可以在以下位置找到:

Another error handling ideas can be found in:

  • gin-gonic issue "Question: Handling errors"
  • gin-gonic issue "Question: Status codes in error handling"
  • chirp
  • gin-merry error handler
  • gin-frsh-showerrors

这篇关于更好的错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆