github.com/mundipagg/boleto-api@v0.0.0-20230620145841-3f9ec742599f/api/errors.go (about) 1 package api 2 3 import ( 4 "fmt" 5 "net/http" 6 "runtime/debug" 7 8 "github.com/gin-gonic/gin" 9 "github.com/mundipagg/boleto-api/models" 10 ) 11 12 var validate = map[string]int{ 13 "MP400": http.StatusBadRequest, 14 "MPAmountInCents": http.StatusBadRequest, 15 "MPExpireDate": http.StatusBadRequest, 16 "MPBuyerDocumentType": http.StatusBadRequest, 17 "MPDocumentNumber": http.StatusBadRequest, 18 "MPRecipientDocumentType": http.StatusBadRequest, 19 "MPTimeout": http.StatusGatewayTimeout, 20 "MPOurNumberFail": http.StatusBadGateway, 21 } 22 23 func handleErrors(c *gin.Context) { 24 c.Next() 25 26 var status int 27 var exist bool 28 29 response := getResponseFromContext(c) 30 31 if !qualifiedForNewErrorHandling(c, response) { 32 return 33 } 34 35 bankcode := response.Errors[0].Code 36 if status, exist = validate[bankcode]; !exist { 37 status = getBankFromContext(c).GetErrorsMap()[bankcode] 38 } 39 40 switch status { 41 case http.StatusBadRequest: 42 response.Errors[0].Code = "MP400" 43 c.JSON(http.StatusBadRequest, response) 44 case http.StatusBadGateway: 45 response.Errors[0].Code = "MP502" 46 c.JSON(http.StatusBadGateway, response) 47 case http.StatusGatewayTimeout: 48 response.Errors[0].Code = "MP504" 49 c.JSON(http.StatusGatewayTimeout, response) 50 default: 51 response.Errors[0].Code = "MP500" 52 clientResponse := getResponseError("MP500", "An internal error occurred.") 53 c.JSON(http.StatusInternalServerError, clientResponse) 54 } 55 56 c.Set(responseKey, response) 57 } 58 59 func qualifiedForNewErrorHandling(c *gin.Context, response models.BoletoResponse) bool { 60 if (getBankFromContext(c).GetErrorsMap() != nil && response.HasErrors()) || hasPanic(c) { 61 return true 62 } 63 return false 64 } 65 66 func hasPanic(c *gin.Context) bool { 67 _, exists := c.Get("hasPanic") 68 69 return exists 70 } 71 72 func getErrorCodeToLog(c *gin.Context) string { 73 response := getResponseFromContext(c) 74 if response.HasErrors() { 75 return response.Errors[0].ErrorCode() 76 } 77 return "" 78 } 79 80 func panicRecoveryHandler(c *gin.Context) { 81 defer func() { 82 if rec := recover(); rec != nil { 83 err := fmt.Errorf("an internal error occurred: %v.\ninner exception: %s", rec, string(debug.Stack())) 84 85 errorResponse := getResponseError("MP500", err.Error()) 86 87 c.Set(responseKey, errorResponse) 88 c.Set("hasPanic", true) 89 } 90 }() 91 92 c.Next() 93 } 94 95 func errorResponseToClient(c *gin.Context) { 96 c.Next() 97 98 if hasPanic(c) { 99 errorResponse := getResponseError("MP500", "An internal error occurred.") 100 101 c.JSON(http.StatusInternalServerError, errorResponse) 102 } 103 } 104 105 func getResponseError(code string, message string) models.BoletoResponse { 106 errorResponse := models.BoletoResponse{ 107 Errors: models.NewErrors(), 108 } 109 110 errorResponse.Errors.Append(code, message) 111 112 return errorResponse 113 }