mirror of https://github.com/gin-gonic/gin.git
Better debug logging + unit tests
This commit is contained in:
parent
c391520654
commit
b690611c38
12
debug.go
12
debug.go
|
@ -15,7 +15,7 @@ func IsDebugging() bool {
|
|||
return ginMode == debugCode
|
||||
}
|
||||
|
||||
func debugRoute(httpMethod, absolutePath string, handlers HandlersChain) {
|
||||
func debugPrintRoute(httpMethod, absolutePath string, handlers HandlersChain) {
|
||||
if IsDebugging() {
|
||||
nuHandlers := len(handlers)
|
||||
handlerName := nameOfFunction(handlers[nuHandlers-1])
|
||||
|
@ -28,3 +28,13 @@ func debugPrint(format string, values ...interface{}) {
|
|||
debugLogger.Printf(format, values...)
|
||||
}
|
||||
}
|
||||
|
||||
func debugPrintWARNING() {
|
||||
debugPrint("[WARNING] Running in DEBUG mode! Disable it before going production\n")
|
||||
}
|
||||
|
||||
func debugPrintError(err error) {
|
||||
if err != nil {
|
||||
debugPrint("[ERROR] %v\n", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,17 @@
|
|||
package gin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var cachedDebugLogger *log.Logger = nil
|
||||
|
||||
// TODO
|
||||
// func debugRoute(httpMethod, absolutePath string, handlers HandlersChain) {
|
||||
// func debugPrint(format string, values ...interface{}) {
|
||||
|
@ -22,3 +28,52 @@ func TestIsDebugging(t *testing.T) {
|
|||
SetMode(TestMode)
|
||||
assert.False(t, IsDebugging())
|
||||
}
|
||||
|
||||
func TestDebugPrint(t *testing.T) {
|
||||
var w bytes.Buffer
|
||||
setup(&w)
|
||||
defer teardown()
|
||||
|
||||
SetMode(ReleaseMode)
|
||||
debugPrint("DEBUG this!")
|
||||
SetMode(TestMode)
|
||||
debugPrint("DEBUG this!")
|
||||
assert.Empty(t, w.String())
|
||||
|
||||
SetMode(DebugMode)
|
||||
debugPrint("these are %d %s\n", 2, "error messages")
|
||||
assert.Equal(t, w.String(), "[GIN-debug] these are 2 error messages\n")
|
||||
}
|
||||
|
||||
func TestDebugPrintError(t *testing.T) {
|
||||
var w bytes.Buffer
|
||||
setup(&w)
|
||||
defer teardown()
|
||||
|
||||
SetMode(DebugMode)
|
||||
debugPrintError(nil)
|
||||
assert.Empty(t, w.String())
|
||||
|
||||
debugPrintError(errors.New("this is an error"))
|
||||
assert.Equal(t, w.String(), "[GIN-debug] [ERROR] this is an error\n")
|
||||
}
|
||||
|
||||
func setup(w io.Writer) {
|
||||
SetMode(DebugMode)
|
||||
if cachedDebugLogger == nil {
|
||||
cachedDebugLogger = debugLogger
|
||||
debugLogger = log.New(w, debugLogger.Prefix(), 0)
|
||||
} else {
|
||||
panic("setup failed")
|
||||
}
|
||||
}
|
||||
|
||||
func teardown() {
|
||||
SetMode(TestMode)
|
||||
if cachedDebugLogger != nil {
|
||||
debugLogger = cachedDebugLogger
|
||||
cachedDebugLogger = nil
|
||||
} else {
|
||||
panic("teardown failed")
|
||||
}
|
||||
}
|
||||
|
|
29
errors.go
29
errors.go
|
@ -10,16 +10,19 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
ErrorTypeInternal = 1 << iota
|
||||
ErrorTypeExternal = 1 << iota
|
||||
ErrorTypeAll = 0xffffffff
|
||||
ErrorTypePrivate = 1 << iota
|
||||
ErrorTypePublic = 1 << iota
|
||||
)
|
||||
|
||||
const (
|
||||
ErrorMaskAny = 0xffffffff
|
||||
)
|
||||
|
||||
// Used internally to collect errors that occurred during an http request.
|
||||
type errorMsg struct {
|
||||
Err string `json:"error"`
|
||||
Type int `json:"-"`
|
||||
Meta interface{} `json:"meta"`
|
||||
Error error `json:"error"`
|
||||
Type int `json:"-"`
|
||||
Meta interface{} `json:"meta"`
|
||||
}
|
||||
|
||||
type errorMsgs []errorMsg
|
||||
|
@ -37,14 +40,24 @@ func (a errorMsgs) ByType(typ int) errorMsgs {
|
|||
return result
|
||||
}
|
||||
|
||||
func (a errorMsgs) Errors() []string {
|
||||
if len(a) == 0 {
|
||||
return []string{}
|
||||
}
|
||||
errors := make([]string, len(a))
|
||||
for i, err := range a {
|
||||
errors[i] = err.Error.Error()
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
func (a errorMsgs) String() string {
|
||||
if len(a) == 0 {
|
||||
return ""
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
for i, msg := range a {
|
||||
text := fmt.Sprintf("Error #%02d: %s\n Meta: %v\n", (i + 1), msg.Err, msg.Meta)
|
||||
buffer.WriteString(text)
|
||||
fmt.Fprintf(&buffer, "Error #%02d: %s\n Meta: %v\n", (i + 1), msg.Error, msg.Meta)
|
||||
}
|
||||
return buffer.String()
|
||||
}
|
||||
|
|
17
gin.go
17
gin.go
|
@ -62,6 +62,7 @@ type (
|
|||
// Returns a new blank Engine instance without any middleware attached.
|
||||
// The most basic configuration
|
||||
func New() *Engine {
|
||||
debugPrintWARNING()
|
||||
engine := &Engine{
|
||||
RouterGroup: RouterGroup{
|
||||
Handlers: nil,
|
||||
|
@ -156,16 +157,20 @@ func (engine *Engine) handle(method, path string, handlers HandlersChain) {
|
|||
root.addRoute(path, handlers)
|
||||
}
|
||||
|
||||
func (engine *Engine) Run(addr string) error {
|
||||
debugPrint("[WARNING] Running in DEBUG mode! Disable it before going production")
|
||||
func (engine *Engine) Run(addr string) (err error) {
|
||||
debugPrint("Listening and serving HTTP on %s\n", addr)
|
||||
return http.ListenAndServe(addr, engine)
|
||||
defer debugPrintError(err)
|
||||
|
||||
err = http.ListenAndServe(addr, engine)
|
||||
return
|
||||
}
|
||||
|
||||
func (engine *Engine) RunTLS(addr string, cert string, key string) error {
|
||||
debugPrint("[WARNING] Running in DEBUG mode! Disable it before going production")
|
||||
func (engine *Engine) RunTLS(addr string, cert string, key string) (err error) {
|
||||
debugPrint("Listening and serving HTTPS on %s\n", addr)
|
||||
return http.ListenAndServeTLS(addr, cert, key, engine)
|
||||
defer debugPrintError(err)
|
||||
|
||||
err = http.ListenAndServe(addr, engine)
|
||||
return
|
||||
}
|
||||
|
||||
// ServeHTTP makes the router implement the http.Handler interface.
|
||||
|
|
|
@ -45,7 +45,7 @@ func (group *RouterGroup) Group(relativePath string, handlers ...HandlerFunc) *R
|
|||
func (group *RouterGroup) Handle(httpMethod, relativePath string, handlers HandlersChain) {
|
||||
absolutePath := group.calculateAbsolutePath(relativePath)
|
||||
handlers = group.combineHandlers(handlers)
|
||||
debugRoute(httpMethod, absolutePath, handlers)
|
||||
debugPrintRoute(httpMethod, absolutePath, handlers)
|
||||
group.engine.handle(httpMethod, absolutePath, handlers)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue