mirror of https://github.com/gin-gonic/gin.git
Fixes errors
This commit is contained in:
parent
421793bfba
commit
99694bb716
28
context.go
28
context.go
|
@ -40,13 +40,18 @@ type Params []Param
|
|||
|
||||
// ByName returns the value of the first Param which key matches the given name.
|
||||
// If no matching Param is found, an empty string is returned.
|
||||
func (ps Params) ByName(name string) string {
|
||||
func (ps Params) Get(name string) (string, bool) {
|
||||
for _, entry := range ps {
|
||||
if entry.Key == name {
|
||||
return entry.Value
|
||||
return entry.Value, true
|
||||
}
|
||||
}
|
||||
return ""
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (ps Params) ByName(name string) (va string) {
|
||||
va, _ = ps.Get(name)
|
||||
return
|
||||
}
|
||||
|
||||
// Context is the most important part of gin. It allows us to pass variables between middleware,
|
||||
|
@ -138,8 +143,8 @@ func (c *Context) Fail(code int, err error) {
|
|||
|
||||
func (c *Context) ErrorTyped(err error, typ int, meta interface{}) {
|
||||
c.Errors = append(c.Errors, errorMsg{
|
||||
Err: err.Error(),
|
||||
Type: typ,
|
||||
Error: err,
|
||||
Flags: typ,
|
||||
Meta: meta,
|
||||
})
|
||||
}
|
||||
|
@ -154,7 +159,7 @@ func (c *Context) Error(err error, meta interface{}) {
|
|||
func (c *Context) LastError() error {
|
||||
nuErrors := len(c.Errors)
|
||||
if nuErrors > 0 {
|
||||
return errors.New(c.Errors[nuErrors-1].Err)
|
||||
return c.Errors[nuErrors-1].Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -203,8 +208,7 @@ func (c *Context) DefaultParamValue(key, defaultValue string) string {
|
|||
}
|
||||
|
||||
func (c *Context) paramValue(key string) (string, bool) {
|
||||
va := c.Params.ByName(key)
|
||||
return va, len(va) > 0
|
||||
return c.Params.Get(key)
|
||||
}
|
||||
|
||||
func (c *Context) formValue(key string) (string, bool) {
|
||||
|
@ -231,17 +235,17 @@ func (c *Context) postFormValue(key string) (string, bool) {
|
|||
|
||||
// Sets a new pair key/value just for the specified context.
|
||||
// It also lazy initializes the hashmap.
|
||||
func (c *Context) Set(key string, item interface{}) {
|
||||
func (c *Context) Set(key string, value interface{}) {
|
||||
if c.Keys == nil {
|
||||
c.Keys = make(map[string]interface{})
|
||||
}
|
||||
c.Keys[key] = item
|
||||
c.Keys[key] = value
|
||||
}
|
||||
|
||||
// Get returns the value for the given key or an error if the key does not exist.
|
||||
func (c *Context) Get(key string) (value interface{}, ok bool) {
|
||||
func (c *Context) Get(key string) (value interface{}, exists bool) {
|
||||
if c.Keys != nil {
|
||||
value, ok = c.Keys[key]
|
||||
value, exists = c.Keys[key]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -318,13 +318,13 @@ func TestContextError(t *testing.T) {
|
|||
assert.Equal(t, c.Errors.String(), "Error #01: first error\n Meta: some data\n"+
|
||||
"Error #02: second error\n Meta: some data 2\n")
|
||||
|
||||
assert.Equal(t, c.Errors[0].Err, "first error")
|
||||
assert.Equal(t, c.Errors[0].Error, errors.New("first error"))
|
||||
assert.Equal(t, c.Errors[0].Meta, "some data")
|
||||
assert.Equal(t, c.Errors[0].Type, ErrorTypeExternal)
|
||||
assert.Equal(t, c.Errors[0].Flags, ErrorTypeExternal)
|
||||
|
||||
assert.Equal(t, c.Errors[1].Err, "second error")
|
||||
assert.Equal(t, c.Errors[1].Error, errors.New("second error"))
|
||||
assert.Equal(t, c.Errors[1].Meta, "some data 2")
|
||||
assert.Equal(t, c.Errors[1].Type, ErrorTypeExternal)
|
||||
assert.Equal(t, c.Errors[1].Flags, ErrorTypeExternal)
|
||||
}
|
||||
|
||||
func TestContextTypedError(t *testing.T) {
|
||||
|
@ -337,11 +337,11 @@ func TestContextTypedError(t *testing.T) {
|
|||
c.ErrorTyped(errors.New("interno 2"), ErrorTypeInternal, nil)
|
||||
|
||||
for _, err := range c.Errors.ByType(ErrorTypeExternal) {
|
||||
assert.Equal(t, err.Type, ErrorTypeExternal)
|
||||
assert.Equal(t, err.Flags, ErrorTypeExternal)
|
||||
}
|
||||
|
||||
for _, err := range c.Errors.ByType(ErrorTypeInternal) {
|
||||
assert.Equal(t, err.Type, ErrorTypeInternal)
|
||||
assert.Equal(t, err.Flags, ErrorTypeInternal)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
19
errors.go
19
errors.go
|
@ -10,18 +10,15 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
ErrorTypePrivate = 1 << iota
|
||||
ErrorTypePublic = 1 << iota
|
||||
)
|
||||
|
||||
const (
|
||||
ErrorMaskAny = 0xffffffff
|
||||
ErrorTypeInternal = 1 << iota
|
||||
ErrorTypeExternal = 1 << iota
|
||||
ErrorTypeAny = 0xffffffff
|
||||
)
|
||||
|
||||
// Used internally to collect errors that occurred during an http request.
|
||||
type errorMsg struct {
|
||||
Error error `json:"error"`
|
||||
Type int `json:"-"`
|
||||
Flags int `json:"-"`
|
||||
Meta interface{} `json:"meta"`
|
||||
}
|
||||
|
||||
|
@ -33,7 +30,7 @@ func (a errorMsgs) ByType(typ int) errorMsgs {
|
|||
}
|
||||
result := make(errorMsgs, 0, len(a))
|
||||
for _, msg := range a {
|
||||
if msg.Type&typ > 0 {
|
||||
if msg.Flags&typ > 0 {
|
||||
result = append(result, msg)
|
||||
}
|
||||
}
|
||||
|
@ -44,11 +41,11 @@ func (a errorMsgs) Errors() []string {
|
|||
if len(a) == 0 {
|
||||
return []string{}
|
||||
}
|
||||
errors := make([]string, len(a))
|
||||
errorStrings := make([]string, len(a))
|
||||
for i, err := range a {
|
||||
errors[i] = err.Error.Error()
|
||||
errorStrings[i] = err.Error.Error()
|
||||
}
|
||||
return errors
|
||||
return errorStrings
|
||||
}
|
||||
|
||||
func (a errorMsgs) String() string {
|
||||
|
|
|
@ -22,7 +22,7 @@ var (
|
|||
)
|
||||
|
||||
func ErrorLogger() HandlerFunc {
|
||||
return ErrorLoggerT(ErrorTypeAll)
|
||||
return ErrorLoggerT(ErrorTypeAny)
|
||||
}
|
||||
|
||||
func ErrorLoggerT(typ int) HandlerFunc {
|
||||
|
@ -31,17 +31,17 @@ func ErrorLoggerT(typ int) HandlerFunc {
|
|||
|
||||
if !c.Writer.Written() {
|
||||
if errs := c.Errors.ByType(typ); len(errs) > 0 {
|
||||
c.JSON(-1, errs)
|
||||
c.JSON(-1, errs.Errors())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Logger() HandlerFunc {
|
||||
return LoggerWithFile(DefaultWriter)
|
||||
return LoggerWithWriter(DefaultWriter)
|
||||
}
|
||||
|
||||
func LoggerWithFile(out io.Writer) HandlerFunc {
|
||||
func LoggerWithWriter(out io.Writer) HandlerFunc {
|
||||
return func(c *Context) {
|
||||
// Start timer
|
||||
start := time.Now()
|
||||
|
|
|
@ -24,7 +24,7 @@ func init() {
|
|||
func TestLogger(t *testing.T) {
|
||||
buffer := new(bytes.Buffer)
|
||||
router := New()
|
||||
router.Use(LoggerWithFile(buffer))
|
||||
router.Use(LoggerWithWriter(buffer))
|
||||
router.GET("/example", func(c *Context) {})
|
||||
|
||||
performRequest(router, "GET", "/example")
|
||||
|
|
|
@ -23,10 +23,10 @@ var (
|
|||
// Recovery returns a middleware that recovers from any panics and writes a 500 if there was one.
|
||||
// While Gin is in development mode, Recovery will also output the panic as HTML.
|
||||
func Recovery() HandlerFunc {
|
||||
return RecoveryWithFile(DefaultWriter)
|
||||
return RecoveryWithWriter(DefaultWriter)
|
||||
}
|
||||
|
||||
func RecoveryWithFile(out io.Writer) HandlerFunc {
|
||||
func RecoveryWithWriter(out io.Writer) HandlerFunc {
|
||||
var logger *log.Logger
|
||||
if out != nil {
|
||||
logger = log.New(out, "", log.LstdFlags)
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
func TestPanicInHandler(t *testing.T) {
|
||||
buffer := new(bytes.Buffer)
|
||||
router := New()
|
||||
router.Use(RecoveryWithFile(buffer))
|
||||
router.Use(RecoveryWithWriter(buffer))
|
||||
router.GET("/recovery", func(_ *Context) {
|
||||
panic("Oupps, Houston, we have a problem")
|
||||
})
|
||||
|
@ -30,7 +30,7 @@ func TestPanicInHandler(t *testing.T) {
|
|||
// TestPanicWithAbort assert that panic has been recovered even if context.Abort was used.
|
||||
func TestPanicWithAbort(t *testing.T) {
|
||||
router := New()
|
||||
router.Use(RecoveryWithFile(nil))
|
||||
router.Use(RecoveryWithWriter(nil))
|
||||
router.GET("/recovery", func(c *Context) {
|
||||
c.AbortWithStatus(400)
|
||||
panic("Oupps, Houston, we have a problem")
|
||||
|
|
|
@ -6,7 +6,6 @@ package gin
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
@ -46,7 +45,7 @@ func (w *responseWriter) WriteHeader(code int) {
|
|||
if code > 0 {
|
||||
w.status = code
|
||||
if w.Written() {
|
||||
log.Println("[GIN] WARNING. Headers were already written!")
|
||||
debugPrint("[WARNING] Headers were already written")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ func TestFunctionName(t *testing.T) {
|
|||
}
|
||||
|
||||
func somefunction() {
|
||||
|
||||
// this empty function is used by TestFunctionName()
|
||||
}
|
||||
|
||||
func TestJoinPaths(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue