Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display custom error and abort in Golang Gin

Tags:

go

I want to Abort with status and json body if any errors. i don't want to use repeated if condition over and over again.

f, err := os.Create(file)

if(err != nil){
  c.JSON(200, gin.H{"error": true,"message":err.Error() })
  return
}

f, err := os.Create(file)
Error(c,err)

but this function is not aborting

func Error(c *gin.Context,err error) {
  if(err != nil){
  c.JSON(200, gin.H{"status": false,"message":err.Error() })
  c.Error(err)
  c.Abort()
}
like image 806
Ram Avatar asked Sep 07 '19 21:09

Ram


People also ask

How do I create a Golang error?

Custom Errors in Golang In Go, we can create custom errors by implementing an error interface in a struct. Here, the Error() method returns an error message in string form if there is an error. Otherwise, it returns nil . Now, to create a custom error, we have to implement the Error() method on a Go struct.

What is C * gin context?

Returns the specified key from a POST urlencoded form or multipart form when it exists, otherwise it returns the specified defaultValue string. func SomeHandler(c *gin. Context) { key := c. PostForm("key", "default value")

What is gin Default ()?

gin. Default() creates a Gin router with default middleware: logger and recovery middleware. Next, we make a handler using router. GET(path, handle) , where path is the relative path,​ and handle is the handler function that takes *gin. Context as an argument.

What is gin Handlerfunc?

Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to httprouter. If you need performance and good productivity, you will love Gin.


1 Answers

Abort, as stated in the documentation, is for aborting the chain of middleware, not to stop the current handler from executing.

The error checking is a feature of Go and you'll just have to do it, the same as everyone else.

However you can simplify your error checking to some extent. For example one solution could be something like this:

func Error(c *gin.Context, err error) bool {
    if err != nil {
        c.Error(err)
        c.AbortWithStatusJSON(http.StatusInternalServerError , gin.H{"status": false, "message": err.Error()})
        return true // signal that there was an error and the caller should return
    }
    return false // no error, can continue
}

And then your handler would look like this:

func MyHandler(c *gin.Context) {
    f, err := os.Create(file)
    if Error(c, err) {
        return // exit
    }
    
    // continue
}

Another approach, and in my mind the more idiomatic one, would be to change the handler to have an error return argument and then have a wrapper that takes these error-returning handlers and returns a valid gin handler, and then this returned gin handler can deal with the error value however you see fit.

// error returning handler
func MyHandler(c *gin.Context) error {
    f, err := os.Create(file)
    if err != nil {
        return err // exit
    }
    
    // do other stuff...
    
    return nil // all good
}

// function that turns the error-returning handler into a valid gin handler
func GinHandler(myhandler func(c *gin.Context) error) (ginhandler func(c *gin.Context)) {
    return func(c *gin.Context) {
        if err := myhandler(c); err != nil {
            c.Error(err)
            c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"status": false, "message": err.Error()})
        }
    }
}

// and you would register the MyHandler like so...
router := gin.Default()
router.GET("/foobar", GinHandler(MyHandler))
like image 102
mkopriva Avatar answered Sep 28 '22 14:09

mkopriva