From 4495b984d3e60874281f37cdb2dbe2cf1c3874ab Mon Sep 17 00:00:00 2001 From: jloup Date: Wed, 16 May 2018 19:48:05 +0200 Subject: [PATCH] Error flags. --- Gopkg.lock | 10 +++--- api/api.go | 43 +++++++++++++++++-------- api/const.go | 74 ++++++++++++++++++++++++-------------------- api/const_string.go | 14 +-------- api/logger.go | 12 ++++--- api/market_config.go | 19 ++++++++++-- api/routes.go | 2 +- 7 files changed, 101 insertions(+), 73 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 97bf5a5..0123e1c 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -167,7 +167,7 @@ branch = "master" name = "github.com/jloup/utils" packages = ["."] - revision = "3e7b2ea67e9637d153f53ef5ff148f23ee5274d4" + revision = "f1f26d69158b17937cfaabe69379dcc99c194bce" [[projects]] name = "github.com/matcornic/hermes" @@ -243,7 +243,7 @@ "scrypt", "ssh/terminal" ] - revision = "8b1d31080a7692e075c4681cb2458454a1fe0706" + revision = "1a580b3eff7814fc9b40602fd35256c63b50f491" [[projects]] branch = "master" @@ -253,7 +253,7 @@ "html/atom", "websocket" ] - revision = "640f4622ab692b87c2f3a94265e6f579fe38263d" + revision = "2491c5de3490fced2f6cff376127c667efeed857" [[projects]] branch = "master" @@ -262,7 +262,7 @@ "unix", "windows" ] - revision = "78d5f264b493f125018180c204871ecf58a2dce1" + revision = "7c87d13f8e835d2fb3a70a2912c811ed0c1d241b" [[projects]] branch = "v3" @@ -297,6 +297,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "0bc4b06298ce7964140ac7d3e5e58915b01d6a53413af394501d5bf86683d9d7" + inputs-digest = "6bdb5a7d9cbcb4f72cd502105ad19cd635727ef6fb76592704e0ff733fbebf41" solver-name = "gps-cdcl" solver-version = 1 diff --git a/api/api.go b/api/api.go index e011811..f921301 100644 --- a/api/api.go +++ b/api/api.go @@ -5,6 +5,7 @@ import ( "unicode" "github.com/gin-gonic/gin" + "github.com/jloup/utils" ) var CONFIG Config @@ -43,11 +44,30 @@ func SetMailConfig(config MailConfig) { } type Error struct { - Code ErrorCode + Code utils.Flag UserMessage string err error } +func (e Error) FlagString() string { + return e.Code.String() +} + +func (e Error) Flag() utils.Flag { + return e.Code +} + +func (e Error) Msg() string { + return e.UserMessage +} + +func (e Error) ErrorWithCode(f utils.Flag) utils.ErrorFlagged { + if utils.Intersect(e.Code, f) { + return e + } + + return nil +} func (e Error) Err() error { if e.err != nil { return e @@ -64,7 +84,7 @@ func (e Error) Error() string { return "" } -func ErrorIs(err error, code ErrorCode) bool { +func ErrorIs(err error, code utils.Flag) bool { if err == nil { return false } @@ -72,7 +92,7 @@ func ErrorIs(err error, code ErrorCode) bool { if apiError, ok := err.(*Error); !ok { return false } else { - return apiError.Code == code + return utils.Intersect(apiError.Code, code) && apiError.Code.String() == code.String() } } @@ -99,8 +119,8 @@ func ToSnake(in string) string { } type Response struct { - StatusCode Status `json:"-"` - ErrorCode ErrorCode `json:"-"` + StatusCode Status `json:"-"` + ErrorCode utils.Flag `json:"-"` Status string `json:"status"` Code string `json:"code,omitempty"` @@ -110,15 +130,12 @@ type Response struct { func (r Response) populateStatus() Response { r.Status = ToSnake(r.StatusCode.String()) - - if r.ErrorCode != 0 { - r.Code = ToSnake(r.ErrorCode.String()) - } + r.Code = ToSnake(r.ErrorCode.String()) return r } -func ErrorResponse(code ErrorCode, message string) Response { +func ErrorResponse(code utils.Flag, message string) Response { return Response{ StatusCode: NOK, ErrorCode: code, @@ -150,7 +167,7 @@ func M(handler Middleware) gin.HandlerFunc { err := handler(c) if err != nil { - WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c) + WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c) c.Error(err) c.Abort() } else { @@ -166,13 +183,13 @@ type Query interface { func RunQuery(query Query, c *gin.Context) { if err := query.ValidateParams(); err != nil { - WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c) + WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c) c.Error(err) return } if out, err := query.Run(); err != nil { - WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c) + WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c) c.Error(err) } else { WriteJsonResponse(SuccessResponse(out), c) diff --git a/api/const.go b/api/const.go index 2ad4d61..4f608d5 100644 --- a/api/const.go +++ b/api/const.go @@ -1,58 +1,66 @@ package api -import "net/http" +import ( + "net/http" -//go:generate stringer -type=Status,ErrorCode -output const_string.go + "github.com/jloup/utils" +) + +//go:generate stringer -type=Status -output const_string.go type Status uint32 -type ErrorCode uint32 const EXTERNAL_SERVICE_TIMEOUT_SECONDS = 20 const ( OK Status = iota NOK +) - BadRequest ErrorCode = iota + 1 - EmailExists - ExternalServiceTimeout - InternalError - InvalidCredentials - InvalidEmail - InvalidMarketCredentials - MarketCredentialsNotConfigured - IPRestrictedApiKey - InvalidOtp - InvalidPassword - NeedOtpValidation - NotAuthorized - NotFound - OtpAlreadySetup - OtpNotSetup - UserNotConfirmed +var ( + errorFlagCounter utils.Counter = 0 + BadRequest utils.Flag = utils.InitFlag(&errorFlagCounter, "BadRequest") + EmailExists utils.Flag = utils.InitFlag(&errorFlagCounter, "EmailExists") + ExternalServiceTimeout utils.Flag = utils.InitFlag(&errorFlagCounter, "ExternalServiceTimeout") + InternalError utils.Flag = utils.InitFlag(&errorFlagCounter, "InternalError") + InvalidCredentials utils.Flag = utils.InitFlag(&errorFlagCounter, "InvalidCredentials") + InvalidEmail utils.Flag = utils.InitFlag(&errorFlagCounter, "InvalidEmail") + InvalidMarketCredentials utils.Flag = utils.InitFlag(&errorFlagCounter, "InvalidMarketCredentials") + MarketCredentialsNotConfigured utils.Flag = utils.InitFlag(&errorFlagCounter, "MarketCredentialsNotConfigured") + IPRestrictedApiKey utils.Flag = utils.InitFlag(&errorFlagCounter, "IPRestrictedApiKey") + InvalidOtp utils.Flag = utils.InitFlag(&errorFlagCounter, "InvalidOtp") + InvalidPassword utils.Flag = utils.InitFlag(&errorFlagCounter, "InvalidPassword") + NeedOtpValidation utils.Flag = utils.InitFlag(&errorFlagCounter, "NeedOtpValidation") + NotAuthorized utils.Flag = utils.InitFlag(&errorFlagCounter, "NotAuthorized") + NotFound utils.Flag = utils.InitFlag(&errorFlagCounter, "NotFound") + OtpAlreadySetup utils.Flag = utils.InitFlag(&errorFlagCounter, "OtpAlreadySetup") + OtpNotSetup utils.Flag = utils.InitFlag(&errorFlagCounter, "OtpNotSetup") + UserNotConfirmed utils.Flag = utils.InitFlag(&errorFlagCounter, "UserNotConfirmed") + + StatusBadRequest utils.Flag = utils.Join("BadRequest", BadRequest, InvalidPassword, InvalidEmail, InvalidMarketCredentials, IPRestrictedApiKey, MarketCredentialsNotConfigured) + StatusUnauthorized utils.Flag = utils.Join("Unauthorized", InvalidCredentials, InvalidOtp) + StatusForbidden utils.Flag = utils.Join("Forbidden", UserNotConfirmed, NotAuthorized, OtpAlreadySetup, OtpNotSetup, NeedOtpValidation) + StatusConflicts utils.Flag = utils.Join("Conflicts", EmailExists) + StatusNotFound utils.Flag = utils.Join("NotFound", NotFound) + StatusGatewayTimeout utils.Flag = utils.Join("GatewayTimeout", ExternalServiceTimeout) ) -func StatusToHttpCode(status Status, code ErrorCode) int { +func StatusToHttpCode(status Status, code utils.Flag) int { if status == OK { return http.StatusOK } - switch code { - case BadRequest, InvalidPassword, InvalidEmail, InvalidMarketCredentials, IPRestrictedApiKey, MarketCredentialsNotConfigured: + switch { + case utils.Intersect(code, StatusBadRequest): return http.StatusBadRequest - - case InvalidCredentials, InvalidOtp: + case utils.Intersect(code, StatusUnauthorized): return http.StatusUnauthorized - - case UserNotConfirmed, NotAuthorized, OtpAlreadySetup, OtpNotSetup, NeedOtpValidation: + case utils.Intersect(code, StatusForbidden): return http.StatusForbidden - - case EmailExists: + case utils.Intersect(code, StatusConflicts): return http.StatusConflict - - case NotFound: + case utils.Intersect(code, StatusNotFound): return http.StatusNotFound - - case ExternalServiceTimeout: + case utils.Intersect(code, StatusGatewayTimeout): return http.StatusGatewayTimeout } diff --git a/api/const_string.go b/api/const_string.go index 5af7574..c22d1ae 100644 --- a/api/const_string.go +++ b/api/const_string.go @@ -1,4 +1,4 @@ -// Code generated by "stringer -type=Status,ErrorCode -output const_string.go"; DO NOT EDIT. +// Code generated by "stringer -type=Status -output const_string.go"; DO NOT EDIT. package api @@ -14,15 +14,3 @@ func (i Status) String() string { } return _Status_name[_Status_index[i]:_Status_index[i+1]] } - -const _ErrorCode_name = "BadRequestEmailExistsExternalServiceTimeoutInternalErrorInvalidCredentialsInvalidEmailInvalidMarketCredentialsMarketCredentialsNotConfiguredIPRestrictedApiKeyInvalidOtpInvalidPasswordNeedOtpValidationNotAuthorizedNotFoundOtpAlreadySetupOtpNotSetupUserNotConfirmed" - -var _ErrorCode_index = [...]uint16{0, 10, 21, 43, 56, 74, 86, 110, 140, 158, 168, 183, 200, 213, 221, 236, 247, 263} - -func (i ErrorCode) String() string { - i -= 3 - if i >= ErrorCode(len(_ErrorCode_index)-1) { - return "ErrorCode(" + strconv.FormatInt(int64(i+3), 10) + ")" - } - return _ErrorCode_name[_ErrorCode_index[i]:_ErrorCode_index[i+1]] -} diff --git a/api/logger.go b/api/logger.go index a24e08a..5f49d29 100644 --- a/api/logger.go +++ b/api/logger.go @@ -2,7 +2,6 @@ package api import ( "fmt" - "strings" "time" "github.com/Sirupsen/logrus" @@ -51,11 +50,14 @@ func Logger() gin.HandlerFunc { level = logrus.ErrorLevel } - comment := c.Errors.ByType(gin.ErrorTypePrivate).String() - if comment != "" { - msgLog = fmt.Sprintf("%s: %s", msgLog, strings.TrimSpace(comment)) + errors := c.Errors.ByType(gin.ErrorTypePrivate) + + for _, err := range errors { + l.Logf(level, "%s: %s", msgLog, err.Err) } - l.Logf(level, msgLog) + if errors == nil { + l.Logf(level, msgLog) + } } } diff --git a/api/market_config.go b/api/market_config.go index e02c3ba..c7e2e15 100644 --- a/api/market_config.go +++ b/api/market_config.go @@ -5,9 +5,9 @@ import ( "strings" "time" - "github.com/jloup/utils" "git.immae.eu/Cryptoportfolio/Front.git/db" "git.immae.eu/Cryptoportfolio/Front.git/markets" + "github.com/jloup/utils" ) type MarketConfigQuery struct { @@ -97,10 +97,23 @@ func (q TestMarketCredentialsQuery) Run() (interface{}, *Error) { return nil }) - if resultErr != nil { + var newStatus db.MarketConfigStatus = config.Status + + if ErrorIs(resultErr, InvalidMarketCredentials) || ErrorIs(resultErr, IPRestrictedApiKey) || ErrorIs(resultErr, MarketCredentialsNotConfigured) { + newStatus = db.MarketConfigInvalidCredentials + } else if resultErr != nil { + return nil, NewInternalError(resultErr) + } else if resultErr != nil { return nil, NewInternalError(resultErr) } + if newStatus != config.Status { + config, err = db.SetMarketConfigStatus(*config, newStatus) + if err != nil { + return nil, NewInternalError(err) + } + } + return nil, nil } @@ -158,7 +171,7 @@ func (q UpdateMarketConfigQuery) Run() (interface{}, *Error) { var newStatus db.MarketConfigStatus = db.MarketConfigEnabled - if ErrorIs(resultErr, InvalidMarketCredentials) || ErrorIs(resultErr, IPRestrictedApiKey) { + if ErrorIs(resultErr, InvalidMarketCredentials) || ErrorIs(resultErr, IPRestrictedApiKey) || ErrorIs(resultErr, MarketCredentialsNotConfigured) { newStatus = db.MarketConfigInvalidCredentials } else if resultErr != nil { return nil, NewInternalError(resultErr) diff --git a/api/routes.go b/api/routes.go index a102419..671d22e 100644 --- a/api/routes.go +++ b/api/routes.go @@ -99,7 +99,7 @@ func OtpEnrollment(c *gin.Context) { qrPng, secret, err := query.Run() if err != nil { - WriteJsonResponse(ErrorResponse(err.Code, err.UserMessage), c) + WriteJsonResponse(ErrorResponse(err.Flag(), err.UserMessage), c) c.Error(err) return } -- 2.41.0