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.
|
// 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.
|
// 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 {
|
for _, entry := range ps {
|
||||||
if entry.Key == name {
|
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,
|
// 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{}) {
|
func (c *Context) ErrorTyped(err error, typ int, meta interface{}) {
|
||||||
c.Errors = append(c.Errors, errorMsg{
|
c.Errors = append(c.Errors, errorMsg{
|
||||||
Err: err.Error(),
|
Error: err,
|
||||||
Type: typ,
|
Flags: typ,
|
||||||
Meta: meta,
|
Meta: meta,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -154,7 +159,7 @@ func (c *Context) Error(err error, meta interface{}) {
|
||||||
func (c *Context) LastError() error {
|
func (c *Context) LastError() error {
|
||||||
nuErrors := len(c.Errors)
|
nuErrors := len(c.Errors)
|
||||||
if nuErrors > 0 {
|
if nuErrors > 0 {
|
||||||
return errors.New(c.Errors[nuErrors-1].Err)
|
return c.Errors[nuErrors-1].Error
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -203,8 +208,7 @@ func (c *Context) DefaultParamValue(key, defaultValue string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) paramValue(key string) (string, bool) {
|
func (c *Context) paramValue(key string) (string, bool) {
|
||||||
va := c.Params.ByName(key)
|
return c.Params.Get(key)
|
||||||
return va, len(va) > 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) formValue(key string) (string, bool) {
|
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.
|
// Sets a new pair key/value just for the specified context.
|
||||||
// It also lazy initializes the hashmap.
|
// 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 {
|
if c.Keys == nil {
|
||||||
c.Keys = make(map[string]interface{})
|
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.
|
// 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 {
|
if c.Keys != nil {
|
||||||
value, ok = c.Keys[key]
|
value, exists = c.Keys[key]
|
||||||
}
|
}
|
||||||
return
|
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"+
|
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")
|
"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].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].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) {
|
func TestContextTypedError(t *testing.T) {
|
||||||
|
@ -337,11 +337,11 @@ func TestContextTypedError(t *testing.T) {
|
||||||
c.ErrorTyped(errors.New("interno 2"), ErrorTypeInternal, nil)
|
c.ErrorTyped(errors.New("interno 2"), ErrorTypeInternal, nil)
|
||||||
|
|
||||||
for _, err := range c.Errors.ByType(ErrorTypeExternal) {
|
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) {
|
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 (
|
const (
|
||||||
ErrorTypePrivate = 1 << iota
|
ErrorTypeInternal = 1 << iota
|
||||||
ErrorTypePublic = 1 << iota
|
ErrorTypeExternal = 1 << iota
|
||||||
)
|
ErrorTypeAny = 0xffffffff
|
||||||
|
|
||||||
const (
|
|
||||||
ErrorMaskAny = 0xffffffff
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Used internally to collect errors that occurred during an http request.
|
// Used internally to collect errors that occurred during an http request.
|
||||||
type errorMsg struct {
|
type errorMsg struct {
|
||||||
Error error `json:"error"`
|
Error error `json:"error"`
|
||||||
Type int `json:"-"`
|
Flags int `json:"-"`
|
||||||
Meta interface{} `json:"meta"`
|
Meta interface{} `json:"meta"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +30,7 @@ func (a errorMsgs) ByType(typ int) errorMsgs {
|
||||||
}
|
}
|
||||||
result := make(errorMsgs, 0, len(a))
|
result := make(errorMsgs, 0, len(a))
|
||||||
for _, msg := range a {
|
for _, msg := range a {
|
||||||
if msg.Type&typ > 0 {
|
if msg.Flags&typ > 0 {
|
||||||
result = append(result, msg)
|
result = append(result, msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,11 +41,11 @@ func (a errorMsgs) Errors() []string {
|
||||||
if len(a) == 0 {
|
if len(a) == 0 {
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
errors := make([]string, len(a))
|
errorStrings := make([]string, len(a))
|
||||||
for i, err := range 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 {
|
func (a errorMsgs) String() string {
|
||||||
|
|
|
@ -22,7 +22,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func ErrorLogger() HandlerFunc {
|
func ErrorLogger() HandlerFunc {
|
||||||
return ErrorLoggerT(ErrorTypeAll)
|
return ErrorLoggerT(ErrorTypeAny)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ErrorLoggerT(typ int) HandlerFunc {
|
func ErrorLoggerT(typ int) HandlerFunc {
|
||||||
|
@ -31,17 +31,17 @@ func ErrorLoggerT(typ int) HandlerFunc {
|
||||||
|
|
||||||
if !c.Writer.Written() {
|
if !c.Writer.Written() {
|
||||||
if errs := c.Errors.ByType(typ); len(errs) > 0 {
|
if errs := c.Errors.ByType(typ); len(errs) > 0 {
|
||||||
c.JSON(-1, errs)
|
c.JSON(-1, errs.Errors())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Logger() HandlerFunc {
|
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) {
|
return func(c *Context) {
|
||||||
// Start timer
|
// Start timer
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
|
@ -24,7 +24,7 @@ func init() {
|
||||||
func TestLogger(t *testing.T) {
|
func TestLogger(t *testing.T) {
|
||||||
buffer := new(bytes.Buffer)
|
buffer := new(bytes.Buffer)
|
||||||
router := New()
|
router := New()
|
||||||
router.Use(LoggerWithFile(buffer))
|
router.Use(LoggerWithWriter(buffer))
|
||||||
router.GET("/example", func(c *Context) {})
|
router.GET("/example", func(c *Context) {})
|
||||||
|
|
||||||
performRequest(router, "GET", "/example")
|
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.
|
// 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.
|
// While Gin is in development mode, Recovery will also output the panic as HTML.
|
||||||
func Recovery() HandlerFunc {
|
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
|
var logger *log.Logger
|
||||||
if out != nil {
|
if out != nil {
|
||||||
logger = log.New(out, "", log.LstdFlags)
|
logger = log.New(out, "", log.LstdFlags)
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
func TestPanicInHandler(t *testing.T) {
|
func TestPanicInHandler(t *testing.T) {
|
||||||
buffer := new(bytes.Buffer)
|
buffer := new(bytes.Buffer)
|
||||||
router := New()
|
router := New()
|
||||||
router.Use(RecoveryWithFile(buffer))
|
router.Use(RecoveryWithWriter(buffer))
|
||||||
router.GET("/recovery", func(_ *Context) {
|
router.GET("/recovery", func(_ *Context) {
|
||||||
panic("Oupps, Houston, we have a problem")
|
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.
|
// TestPanicWithAbort assert that panic has been recovered even if context.Abort was used.
|
||||||
func TestPanicWithAbort(t *testing.T) {
|
func TestPanicWithAbort(t *testing.T) {
|
||||||
router := New()
|
router := New()
|
||||||
router.Use(RecoveryWithFile(nil))
|
router.Use(RecoveryWithWriter(nil))
|
||||||
router.GET("/recovery", func(c *Context) {
|
router.GET("/recovery", func(c *Context) {
|
||||||
c.AbortWithStatus(400)
|
c.AbortWithStatus(400)
|
||||||
panic("Oupps, Houston, we have a problem")
|
panic("Oupps, Houston, we have a problem")
|
||||||
|
|
|
@ -6,7 +6,6 @@ package gin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
@ -46,7 +45,7 @@ func (w *responseWriter) WriteHeader(code int) {
|
||||||
if code > 0 {
|
if code > 0 {
|
||||||
w.status = code
|
w.status = code
|
||||||
if w.Written() {
|
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() {
|
func somefunction() {
|
||||||
|
// this empty function is used by TestFunctionName()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJoinPaths(t *testing.T) {
|
func TestJoinPaths(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue