github.com/retailcrm/mg-bot-helper@v0.0.0-20201229112329-a17255681a84/src/error_handler.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "net/http" 6 "runtime/debug" 7 8 "github.com/getsentry/raven-go" 9 "github.com/gin-gonic/gin" 10 "github.com/pkg/errors" 11 ) 12 13 type ( 14 ErrorHandlerFunc func(recovery interface{}, c *gin.Context) 15 ) 16 17 func ErrorHandler(handlers ...ErrorHandlerFunc) gin.HandlerFunc { 18 return func(c *gin.Context) { 19 defer func() { 20 rec := recover() 21 for _, handler := range handlers { 22 handler(rec, c) 23 } 24 25 if rec != nil || len(c.Errors) > 0 { 26 c.Abort() 27 } 28 }() 29 30 c.Next() 31 } 32 } 33 34 func ErrorResponseHandler() ErrorHandlerFunc { 35 return func(recovery interface{}, c *gin.Context) { 36 publicErrors := c.Errors.ByType(gin.ErrorTypePublic) 37 privateLen := len(c.Errors.ByType(gin.ErrorTypePrivate)) 38 publicLen := len(publicErrors) 39 40 if privateLen == 0 && publicLen == 0 && recovery == nil { 41 return 42 } 43 44 messagesLen := publicLen 45 if privateLen > 0 || recovery != nil { 46 messagesLen++ 47 } 48 49 messages := make([]string, messagesLen) 50 index := 0 51 for _, err := range publicErrors { 52 messages[index] = err.Error() 53 index++ 54 } 55 56 if privateLen > 0 || recovery != nil { 57 messages[index] = getLocalizedMessage("error_save") 58 } 59 60 c.JSON(http.StatusInternalServerError, gin.H{"error": messages}) 61 } 62 } 63 64 func ErrorCaptureHandler(client *raven.Client, errorsStacktrace bool) ErrorHandlerFunc { 65 return func(recovery interface{}, c *gin.Context) { 66 tags := map[string]string{ 67 "endpoint": c.Request.RequestURI, 68 } 69 70 var ( 71 ok bool 72 conn Connection 73 ) 74 75 connection, ok := c.Get("connection") 76 if ok { 77 conn = connection.(Connection) 78 } 79 80 if conn.APIURL != "" { 81 tags["crm"] = conn.APIURL 82 } 83 84 if conn.ClientID != "" { 85 tags["clientID"] = conn.ClientID 86 } 87 88 if recovery != nil { 89 stacktrace := raven.NewStacktrace(4, 3, nil) 90 recStr := fmt.Sprint(recovery) 91 err := errors.New(recStr) 92 go client.CaptureMessageAndWait( 93 recStr, 94 tags, 95 raven.NewException(err, stacktrace), 96 raven.NewHttp(c.Request), 97 ) 98 } 99 100 for _, err := range c.Errors { 101 if errorsStacktrace { 102 stacktrace := NewRavenStackTrace(client, err.Err, 0) 103 go client.CaptureMessageAndWait( 104 err.Error(), 105 tags, 106 raven.NewException(err.Err, stacktrace), 107 raven.NewHttp(c.Request), 108 ) 109 } else { 110 go client.CaptureErrorAndWait(err.Err, tags) 111 } 112 } 113 } 114 } 115 116 func PanicLogger() ErrorHandlerFunc { 117 return func(recovery interface{}, c *gin.Context) { 118 if recovery != nil { 119 logger.Error(c.Request.RequestURI, recovery) 120 debug.PrintStack() 121 } 122 } 123 } 124 125 func ErrorLogger() ErrorHandlerFunc { 126 return func(recovery interface{}, c *gin.Context) { 127 for _, err := range c.Errors { 128 logger.Error(c.Request.RequestURI, err.Err) 129 } 130 } 131 }