Fix panic stack trace being printed during recovery of broken pipe (#1089)

This commit is contained in:
Justin Israel 2018-02-27 14:04:40 +13:00 committed by Justin Israel
parent 5d3f30cfc8
commit 80916dc43d

View File

@ -10,8 +10,11 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
"net"
"net/http/httputil" "net/http/httputil"
"os"
"runtime" "runtime"
"syscall"
) )
var ( var (
@ -35,12 +38,33 @@ func RecoveryWithWriter(out io.Writer) HandlerFunc {
return func(c *Context) { return func(c *Context) {
defer func() { defer func() {
if err := recover(); err != nil { if err := recover(); err != nil {
if logger != nil { // Check for a broken connection, as it is not really a
stack := stack(3) // condition that warrants a panic stack trace.
httprequest, _ := httputil.DumpRequest(c.Request, false) var brokenPipe bool
logger.Printf("[Recovery] panic recovered:\n%s\n%s\n%s%s", string(httprequest), err, stack, reset) if ne, ok := err.(*net.OpError); ok {
if se, ok := ne.Err.(*os.SyscallError); ok {
if se.Err == syscall.EPIPE || se.Err == syscall.ECONNRESET {
brokenPipe = true
}
}
}
if logger != nil {
httprequest, _ := httputil.DumpRequest(c.Request, false)
if brokenPipe {
logger.Printf("%s\n%s%s", err, string(httprequest), reset)
} else {
logger.Printf("[Recovery] panic recovered:\n%s\n%s\n%s%s",
string(httprequest), err, stack(3), reset)
}
}
// If the connection is dead, we can't write a status to it.
if brokenPipe {
c.Error(err.(error))
c.Abort()
} else {
c.AbortWithStatus(500)
} }
c.AbortWithStatus(500)
} }
}() }()
c.Next() c.Next()