mirror of
				https://github.com/gin-gonic/gin.git
				synced 2025-11-04 09:12:12 +08:00 
			
		
		
		
	Improves error management
This commit is contained in:
		
							parent
							
								
									b5ddd484de
								
							
						
					
					
						commit
						3295c6e9c4
					
				
							
								
								
									
										54
									
								
								gin.go
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								gin.go
									
									
									
									
									
								
							@ -24,18 +24,25 @@ const (
 | 
				
			|||||||
	MIMEPlain  = "text/plain"
 | 
						MIMEPlain  = "text/plain"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						ErrorTypeInternal = 1 << iota
 | 
				
			||||||
 | 
						ErrorTypeExternal = 1 << iota
 | 
				
			||||||
 | 
						ErrorTypeAll      = 0xffffffff
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type (
 | 
					type (
 | 
				
			||||||
	HandlerFunc func(*Context)
 | 
						HandlerFunc func(*Context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	H map[string]interface{}
 | 
						H map[string]interface{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Used internally to collect errors that occurred during an http request.
 | 
						// Used internally to collect errors that occurred during an http request.
 | 
				
			||||||
	ErrorMsg struct {
 | 
						errorMsg struct {
 | 
				
			||||||
		Err  string      `json:"error"`
 | 
							Err  string      `json:"error"`
 | 
				
			||||||
 | 
							Type uint32      `json:"-"`
 | 
				
			||||||
		Meta interface{} `json:"meta"`
 | 
							Meta interface{} `json:"meta"`
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ErrorMsgs []ErrorMsg
 | 
						errorMsgs []errorMsg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Config struct {
 | 
						Config struct {
 | 
				
			||||||
		CacheSize    int
 | 
							CacheSize    int
 | 
				
			||||||
@ -48,7 +55,7 @@ type (
 | 
				
			|||||||
		Req      *http.Request
 | 
							Req      *http.Request
 | 
				
			||||||
		Writer   ResponseWriter
 | 
							Writer   ResponseWriter
 | 
				
			||||||
		Keys     map[string]interface{}
 | 
							Keys     map[string]interface{}
 | 
				
			||||||
		Errors   ErrorMsgs
 | 
							Errors   errorMsgs
 | 
				
			||||||
		Params   httprouter.Params
 | 
							Params   httprouter.Params
 | 
				
			||||||
		Engine   *Engine
 | 
							Engine   *Engine
 | 
				
			||||||
		handlers []HandlerFunc
 | 
							handlers []HandlerFunc
 | 
				
			||||||
@ -102,13 +109,25 @@ func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (a ErrorMsgs) String() string {
 | 
					func (a errorMsgs) ByType(typ uint32) errorMsgs {
 | 
				
			||||||
 | 
						if len(a) == 0 {
 | 
				
			||||||
 | 
							return a
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						result := make(errorMsgs, 0, len(a))
 | 
				
			||||||
 | 
						for _, msg := range a {
 | 
				
			||||||
 | 
							if msg.Type&typ > 0 {
 | 
				
			||||||
 | 
								result = append(result, msg)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return result
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a errorMsgs) String() string {
 | 
				
			||||||
	var buffer bytes.Buffer
 | 
						var buffer bytes.Buffer
 | 
				
			||||||
	for i, msg := range a {
 | 
						for i, msg := range a {
 | 
				
			||||||
		text := fmt.Sprintf("Error #%02d: %s \n     Meta: %v\n", (i + 1), msg.Err, msg.Meta)
 | 
							text := fmt.Sprintf("Error #%02d: %s \n     Meta: %v\n", (i + 1), msg.Err, msg.Meta)
 | 
				
			||||||
		buffer.WriteString(text)
 | 
							buffer.WriteString(text)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	buffer.WriteString("\n")
 | 
					 | 
				
			||||||
	return buffer.String()
 | 
						return buffer.String()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -336,14 +355,19 @@ func (c *Context) Fail(code int, err error) {
 | 
				
			|||||||
	c.Abort(code)
 | 
						c.Abort(code)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Context) ErrorTyped(err error, typ uint32, meta interface{}) {
 | 
				
			||||||
 | 
						c.Errors = append(c.Errors, errorMsg{
 | 
				
			||||||
 | 
							Err:  err.Error(),
 | 
				
			||||||
 | 
							Type: typ,
 | 
				
			||||||
 | 
							Meta: meta,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Attaches an error to the current context. The error is pushed to a list of errors.
 | 
					// Attaches an error to the current context. The error is pushed to a list of errors.
 | 
				
			||||||
// It's a good idea to call Error for each error that occurred during the resolution of a request.
 | 
					// It's a good idea to call Error for each error that occurred during the resolution of a request.
 | 
				
			||||||
// A middleware can be used to collect all the errors and push them to a database together, print a log, or append it in the HTTP response.
 | 
					// A middleware can be used to collect all the errors and push them to a database together, print a log, or append it in the HTTP response.
 | 
				
			||||||
func (c *Context) Error(err error, meta interface{}) {
 | 
					func (c *Context) Error(err error, meta interface{}) {
 | 
				
			||||||
	c.Errors = append(c.Errors, ErrorMsg{
 | 
						c.ErrorTyped(err, ErrorTypeExternal, meta)
 | 
				
			||||||
		Err:  err.Error(),
 | 
					 | 
				
			||||||
		Meta: meta,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *Context) LastError() error {
 | 
					func (c *Context) LastError() error {
 | 
				
			||||||
@ -441,8 +465,8 @@ func (c *Context) JSON(code int, obj interface{}) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	encoder := json.NewEncoder(c.Writer)
 | 
						encoder := json.NewEncoder(c.Writer)
 | 
				
			||||||
	if err := encoder.Encode(obj); err != nil {
 | 
						if err := encoder.Encode(obj); err != nil {
 | 
				
			||||||
		c.Error(err, obj)
 | 
							c.ErrorTyped(err, ErrorTypeInternal, obj)
 | 
				
			||||||
		http.Error(c.Writer, err.Error(), 500)
 | 
							c.Abort(500)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -455,8 +479,8 @@ func (c *Context) XML(code int, obj interface{}) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	encoder := xml.NewEncoder(c.Writer)
 | 
						encoder := xml.NewEncoder(c.Writer)
 | 
				
			||||||
	if err := encoder.Encode(obj); err != nil {
 | 
						if err := encoder.Encode(obj); err != nil {
 | 
				
			||||||
		c.Error(err, obj)
 | 
							c.ErrorTyped(err, ErrorTypeInternal, obj)
 | 
				
			||||||
		http.Error(c.Writer, err.Error(), 500)
 | 
							c.Abort(500)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -469,11 +493,11 @@ func (c *Context) HTML(code int, name string, data interface{}) {
 | 
				
			|||||||
		c.Writer.WriteHeader(code)
 | 
							c.Writer.WriteHeader(code)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := c.Engine.HTMLTemplates.ExecuteTemplate(c.Writer, name, data); err != nil {
 | 
						if err := c.Engine.HTMLTemplates.ExecuteTemplate(c.Writer, name, data); err != nil {
 | 
				
			||||||
		c.Error(err, map[string]interface{}{
 | 
							c.ErrorTyped(err, ErrorTypeInternal, H{
 | 
				
			||||||
			"name": name,
 | 
								"name": name,
 | 
				
			||||||
			"data": data,
 | 
								"data": data,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		http.Error(c.Writer, err.Error(), 500)
 | 
							c.Abort(500)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -7,10 +7,15 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ErrorLogger() HandlerFunc {
 | 
					func ErrorLogger() HandlerFunc {
 | 
				
			||||||
 | 
						return ErrorLoggerT(ErrorTypeAll)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func ErrorLoggerT(typ uint32) HandlerFunc {
 | 
				
			||||||
	return func(c *Context) {
 | 
						return func(c *Context) {
 | 
				
			||||||
		c.Next()
 | 
							c.Next()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if len(c.Errors) > 0 {
 | 
							errs := c.Errors.ByType(typ)
 | 
				
			||||||
 | 
							if len(errs) > 0 {
 | 
				
			||||||
			// -1 status code = do not change current one
 | 
								// -1 status code = do not change current one
 | 
				
			||||||
			c.JSON(-1, c.Errors)
 | 
								c.JSON(-1, c.Errors)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user