catch request panics in goroutine

the async stuff uses carlos supervisor thing but in the normal request path we
aren't catching any panics and returning a 500 to user (conn just gets
closed & server dies). should catch any mistakes we might make, or any one of
the 10000 libraries we're importing.

closes #150
This commit is contained in:
Reed Allman
2017-07-26 04:22:58 -07:00
parent 42fb496036
commit 13f822ad7f

View File

@@ -14,12 +14,6 @@ import (
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/ccirello/supervisor" "github.com/ccirello/supervisor"
"github.com/gin-gonic/gin"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/openzipkin/zipkin-go-opentracing"
"github.com/patrickmn/go-cache"
"github.com/spf13/viper"
"github.com/fnproject/fn/api" "github.com/fnproject/fn/api"
"github.com/fnproject/fn/api/datastore" "github.com/fnproject/fn/api/datastore"
"github.com/fnproject/fn/api/id" "github.com/fnproject/fn/api/id"
@@ -28,6 +22,12 @@ import (
"github.com/fnproject/fn/api/mqs" "github.com/fnproject/fn/api/mqs"
"github.com/fnproject/fn/api/runner" "github.com/fnproject/fn/api/runner"
"github.com/fnproject/fn/api/runner/common" "github.com/fnproject/fn/api/runner/common"
"github.com/gin-gonic/gin"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/openzipkin/zipkin-go-opentracing"
"github.com/patrickmn/go-cache"
"github.com/spf13/viper"
) )
const ( const (
@@ -109,7 +109,7 @@ func New(ctx context.Context, ds models.Datastore, mq models.MessageQueue, logDB
setMachineId() setMachineId()
setTracer() setTracer()
s.Router.Use(loggerWrap, traceWrap) s.Router.Use(loggerWrap, traceWrap, panicWrap)
s.bindHandlers(ctx) s.bindHandlers(ctx)
for _, opt := range opts { for _, opt := range opts {
@@ -203,6 +203,19 @@ func whoAmI() net.IP {
return nil return nil
} }
func panicWrap(c *gin.Context) {
defer func(c *gin.Context) {
if rec := recover(); rec != nil {
err, ok := rec.(error)
if !ok {
err = fmt.Errorf("fn: %v", rec)
}
handleErrorResponse(c, err)
}
}(c)
c.Next()
}
func loggerWrap(c *gin.Context) { func loggerWrap(c *gin.Context) {
ctx, _ := common.LoggerWithFields(c.Request.Context(), extractFields(c)) ctx, _ := common.LoggerWithFields(c.Request.Context(), extractFields(c))
@@ -295,15 +308,15 @@ func (s *Server) startGears(ctx context.Context) {
} }
const runHeader = ` const runHeader = `
____ __ ____ __
/ __ \_________ ______/ /__ / __ \_________ ______/ /__
/ / / / ___/ __ / ___/ / _ \ / / / / ___/ __ / ___/ / _ \
/ /_/ / / / /_/ / /__/ / __/ / /_/ / / / /_/ / /__/ / __/
\_________ \__,_/\___/_/\____ \_________ \__,_/\___/_/\____
/ ____/_ __ ___ _____/ /_( )___ ____ _____ / ____/_ __ ___ _____/ /_( )___ ____ _____
/ /_ / / / / __ \/ ___/ __/ / __ \/ __ \/ ___/ / /_ / / / / __ \/ ___/ __/ / __ \/ __ \/ ___/
/ __/ / /_/ / / / / /__/ /_/ / /_/ / / / (__ ) / __/ / /_/ / / / / /__/ /_/ / /_/ / / / (__ )
/_/ \____/_/ /_/\___/\__/_/\____/_/ /_/____/ /_/ \____/_/ /_/\___/\__/_/\____/_/ /_/____/
` `
fmt.Println(runHeader) fmt.Println(runHeader)
logrus.Infof("Serving Functions API on address `%s`", listen) logrus.Infof("Serving Functions API on address `%s`", listen)