Comments (16)
Gin has a built-in error management.
You can do this:
r := gin.Default()
r.Use(gin.ErrorLogger()) // this will print all the errors
// r.Use(gin.ErrorLoggerT(gin.ErrorTypeExternal) // prints all the errors that come from you
r.GET("/path", func(c *gin.Context) {
c.Fail(404, errors.New(errorMessage))
}
If you use the built-in error management, you do not have to change your code when entering production, simply do not use the ErrorLogger()
from gin.
That's not what I mean. You surely receive the error added in the logger provided, but what about the page body? What if I want to add a JSON response as a page body? Currently, looks very hack-ish to do by doing those 3 lines added in the previous comment, but there are several frameworks who actually has a function to stop execution of following handlers and show a response body of whatever we like, such as JSON, XML or plain text.
With your response, I'm assured to get an error logged in the logger, but the user will only see their 4-oh-4 browser's page, but nothing else.
from gin.
Have you tried it?
ErrorLogger prints it in the body!
see the implementation here: https://github.com/gin-gonic/gin/blob/master/logger.go#L13-L23
Maybe ErrorLogger
is a bad name
from gin.
you could even create your our "error printer" middleware you can do whatever you want, print in a log, in the http response body, send them to sentry...
from gin.
Yeah, maybe the name isn't properly self-explanatory. Also, I'm curious: ErrorLoggerT
looks like it is actually calling c.Next()
so that's not preventing the execution of next middlewares. Is that right?
from gin.
c.Next() is used to execute the next handlers in the same stack frame.
func(c *gin.Context) {
// before your logic
c.Next() //your logic (handlers) are called "inside" Next()
// after your logic
// now we can read the errors array c.Errors and do whatever you want
}
so no!, Next() never change the flow order, or prevent the execution, it just allows the developers to execute the next handlers in the chain before retuning the current handler.
from gin.
You should do this:
r := gin.Default()
// this middleware will write the errors submitted from `c.Fail/c.Error` to the response body.
r.Use(gin.ErrorLogger(gin.ErrorTypeExternal))
....
func processing(c *gin.Context) {
if err == nil {
c.JSON(200, gin.H{"status": "everything worked fine"})
} else {
c.Fail(404, errors.New(errorMessage))
}
that simple! if you need custom error management feel free to implement your own middleware (it's like another handler) and read this variable: c.Errors
from gin.
Thank you. That's more like an answer I could understand being just a guy recently switching to gin-gonic. :)
from gin.
Awesome, please let me know if you have ideas to improve the current error management.
Right now I have an idea, c.Fail
should allow any kind of type as data, not just error, so you could do this:
c.Fail(500, gin.H{"complex":"data"})
from gin.
Something like that was the thing I was looking for in the first place: a way to directly send proper data to the destination. gin.H
could be parsed there as JSON or even XML so there's no need to send an error
element to c.Fail
.
from gin.
Think about this way: if there's a c.JSON
and c.XML
there should be a way to send a, i.e., 404 or 400 with those in mind, like c.AbortJSON()
and c.AbortXML()
. Also, there should be an option to cancel next handlers (if needed).
Let me tell you my use case: I was trying to create an API where the requests to a certain url contains in the path the customer ID, like /api/v1/:customer_id/products/add
, so all of the URLs for that customer starts with the :customer_id
parameter. I created a middleware so I could pre-check for the existence of the given customer_id and, if it wasn't found, send a 404 with a JSON body { "error": "customer not found" }
. I've tried with the code I pasted on the first comment, but looks so hackish, so I thought to ask here if there was a better way. My API is sending JSON responses so it makes sense to send JSON, but the API could also be in XML.
from gin.
You can also do:
c.JSON(404, errordata)
c.Abort(-1)
I think this is a pretty good solution for your problem.
from gin.
some code from my startup:
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
// Try to get an authorization pass.
// We provide a AuthRequest and we should get AuthPass in response
pass, err := SERVER.GetAuthPass(AuthRequest{
UserId: c.Request.Header.Get("F_UserID"),
Token: c.Request.Header.Get("F_Token"),
UDID: c.Request.Header.Get("F_UDID"),
})
if err != nil {
// Unauthorized
c.Fail(401, err)
} else {
// Map authpass to the current http request
c.Set("auth", pass)
}
}
}
we do not use:
c.JSON(404, errordata)
c.Abort(-1)
because in our case, the error could be security related, we do not want to show it in production. But in your case looks completely fine!
from gin.
Hi! Please, could you mention this on the README.md, at least in one example? That would spare others searching in discussions for how to handle errors in gin. Thank you.
PS: nice framework!
from gin.
Currently i ama getting type *gin.Context has no field or method Fail)
I have attached the error logger like so
router.Use(gin.ErrorLogger(gin.ErrorTypeExternal))
Was this feature removed or am i doing something wrong ?
from gin.
c.Fail undefined (type *gin.Context has no field or method Fail)
from gin.
Related Issues (20)
- Does gin.Recovery() run before or after Group middleware? HOT 1
- How can i prevent a http connection to close HOT 3
- BasicAuth is not suitable for proxy auth
- Can't get status as expected from context.Status() HOT 1
- Gin Context implementation breaks context.Context contract HOT 3
- [Suggestions] Introducing an AI-powered robot to assist with daily issue and pull request (PR) tasks.
- Need c.JSON() response like behaviour for c.SSEvent() response for supporting first party clients like OpenAI SDK HOT 2
- custom time.Time type can not use bindQuery get a value. HOT 3
- configure server parameters HOT 1
- The binding:"required" tag does not seem to work for struct types HOT 3
- Is there a way to preserve order in JSON on response? HOT 1
- redirect is not success HOT 1
- I want to use shouldmindbodywith first and then use formafile, but it doesn't work right now HOT 3
- Extend the routing tree entry
- Transparent decompression for gzip, deflate, etc? HOT 1
- Custom time.Time type can not use bindQuery get a value 2 HOT 2
- http: response.Write on hijacked connection from github.com/gin-gonic/gin.(*responseWriter).Write (response_writer.go:83) HOT 1
- Suggestion: Move Print Debug to Run() functions? HOT 7
- AbortWithStatusJSON doesn't abort context HOT 2
- I translated `tree.go` into java
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gin.