diff --git a/exception/common.go b/exception/common.go index 7c318ae..2d7795e 100644 --- a/exception/common.go +++ b/exception/common.go @@ -1,6 +1,12 @@ package exception const ( - CommonErrorInvalidInput = "00001" - CommonErrorUnauthorized = "00002" + CommonErrorInvalidInput = "00001" + CommonErrorUnauthorized = "00002" + CommonErrorInternal = "00003" + CommonErrorPermissionDenied = "00004" + CommonErrorUuidParseFailed = "00005" + CommonErrorDatabase = "00006" + CommonErrorMissingUserId = "00007" + CommonErrorUserNotFound = "00008" ) diff --git a/exception/specific.go b/exception/specific.go index 58e743b..56f997f 100644 --- a/exception/specific.go +++ b/exception/specific.go @@ -2,4 +2,59 @@ package exception const ( ApiVersionNotFound = "00001" + + // Auth Service + // Endpoint: AuthRedirectEndpoint (01) + AuthRedirectTokenInvalid = "00001" + AuthRedirectClientNotFound = "00002" + AuthRedirectUriMismatch = "00003" + AuthRedirectInvalidUri = "00004" + + // Endpoint: AuthMagicEndpoint (02) + AuthMagicTurnstileFailed = "00001" + AuthMagicCodeGenFailed = "00002" + AuthMagicInvalidExternalUrl = "00003" + AuthMagicInvalidEmailConfig = "00004" + + // Endpoint: AuthTokenEndpoint (03) + AuthTokenInvalidToken = "00001" + AuthTokenGenFailed = "00002" + + // Endpoint: AuthRefreshEndpoint (04) + AuthRefreshInvalidToken = "00001" + AuthRefreshRenewFailed = "00002" + + // Endpoint: AuthExchangeEndpoint (05) + AuthExchangeGetUserIdFailed = "00001" + AuthExchangeCodeGenFailed = "00002" + AuthExchangeInvalidRedirectUri = "00003" + + // Event Service + // Endpoint: EventInfoEndpoint (01) + EventInfoNotFound = "00001" + + // Endpoint: EventCheckinEndpoint (02) + EventCheckinGenCodeFailed = "00001" + + // Endpoint: EventCheckinQueryEndpoint (03) + EventCheckinQueryRecordNotFound = "00001" + + // Endpoint: EventCheckinSubmitEndpoint (04) + // (None) + + // User Service + // Endpoint: UserInfoEndpoint (01) + // (None) + + // Endpoint: UserUpdateEndpoint (02) + // (None) + + // Endpoint: UserListEndpoint (03) + UserListMeilisearchFailed = "00001" + + // Endpoint: UserFullEndpoint (04) + // (None) + + // Endpoint: UserCreateEndpoint (05) + // (None) ) diff --git a/middleware/permission.go b/middleware/permission.go index c010197..987b3bc 100644 --- a/middleware/permission.go +++ b/middleware/permission.go @@ -2,6 +2,7 @@ package middleware import ( "nixcn-cms/data" + "nixcn-cms/exception" "nixcn-cms/utils" "github.com/gin-gonic/gin" @@ -15,19 +16,40 @@ func Permission(requiredLevel uint) gin.HandlerFunc { if !ok { userIdOrig, ok := c.Get("user_id") if !ok || userIdOrig.(string) == "" { - utils.HttpAbort(c, 401, "", "missing user id") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.MiddlewarePermissionService). + SetEndpoint(exception.MiddlewareEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorMissingUserId). + Build() + utils.HttpAbort(c, 401, errorCode) return } userId, err := uuid.Parse(userIdOrig.(string)) if err != nil { - utils.HttpAbort(c, 500, "", "error parsing user id") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.MiddlewarePermissionService). + SetEndpoint(exception.MiddlewareEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUuidParseFailed). + Build() + utils.HttpAbort(c, 500, errorCode) return } userData, err := new(data.User).GetByUserId(userId) if err != nil { - utils.HttpAbort(c, 404, "", "user not found") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.MiddlewarePermissionService). + SetEndpoint(exception.MiddlewareEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUserNotFound). + Build() + utils.HttpAbort(c, 404, errorCode) return } @@ -38,7 +60,14 @@ func Permission(requiredLevel uint) gin.HandlerFunc { } if permissionLevel < requiredLevel { - utils.HttpAbort(c, 403, "", "permission denied") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.MiddlewarePermissionService). + SetEndpoint(exception.MiddlewareEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorPermissionDenied). + Build() + utils.HttpAbort(c, 403, errorCode) return } diff --git a/service/auth/exchange.go b/service/auth/exchange.go index fa5c62c..c1227a4 100644 --- a/service/auth/exchange.go +++ b/service/auth/exchange.go @@ -4,6 +4,7 @@ import ( "fmt" "net/url" "nixcn-cms/data" + "nixcn-cms/exception" "nixcn-cms/pkgs/authcode" "nixcn-cms/utils" @@ -23,38 +24,80 @@ func Exchange(c *gin.Context) { err := c.ShouldBindJSON(&exchangeReq) if err != nil { fmt.Println(err) - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthExchangeEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } userIdOrig, ok := c.Get("user_id") if !ok { - utils.HttpResponse(c, 401, "", "unauthorized") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthExchangeEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUnauthorized). + Build() + utils.HttpResponse(c, 401, errorCode) return } userId, err := uuid.Parse(userIdOrig.(string)) if err != nil { - utils.HttpResponse(c, 500, "", "failed to parse uuid") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthExchangeEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUuidParseFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } userData := new(data.User) user, err := userData.GetByUserId(userId) if err != nil { - utils.HttpResponse(c, 500, "", "failed to get user id") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthExchangeEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthExchangeGetUserIdFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } code, err := authcode.NewAuthCode(exchangeReq.ClientId, user.Email) if err != nil { - utils.HttpResponse(c, 500, "", "code gen failed") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthExchangeEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthExchangeCodeGenFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } url, err := url.Parse(exchangeReq.RedirectUri) if err != nil { - utils.HttpResponse(c, 400, "", "invalid redirect uri") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthExchangeEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthExchangeInvalidRedirectUri). + Build() + utils.HttpResponse(c, 400, errorCode) return } query := url.Query() diff --git a/service/auth/magic.go b/service/auth/magic.go index c524d4b..40b86fc 100644 --- a/service/auth/magic.go +++ b/service/auth/magic.go @@ -2,6 +2,7 @@ package auth import ( "net/url" + "nixcn-cms/exception" "nixcn-cms/pkgs/authcode" "nixcn-cms/pkgs/email" "nixcn-cms/pkgs/turnstile" @@ -23,27 +24,55 @@ func Magic(c *gin.Context) { // Parse request var req MagicRequest if err := c.ShouldBindJSON(&req); err != nil { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthMagicEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } // Cloudflare turnstile ok, err := turnstile.VerifyTurnstile(req.TurnstileToken, c.ClientIP()) if err != nil || !ok { - utils.HttpResponse(c, 403, "", "turnstile failed") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthMagicEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthMagicTurnstileFailed). + Build() + utils.HttpResponse(c, 403, errorCode) return } code, err := authcode.NewAuthCode(req.ClientId, req.Email) if err != nil { - utils.HttpResponse(c, 500, "", "code gen failed") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthMagicEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthMagicCodeGenFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } externalUrl := viper.GetString("server.external_url") url, err := url.Parse(externalUrl) if err != nil { - utils.HttpResponse(c, 500, "", "invalid external url") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthMagicEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthMagicInvalidExternalUrl). + Build() + utils.HttpResponse(c, 500, errorCode) return } @@ -66,7 +95,14 @@ func Magic(c *gin.Context) { // Send email using resend emailClient, err := new(email.Client).NewSMTPClient() if err != nil { - utils.HttpResponse(c, 500, "", "invalid email config") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthMagicEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthMagicInvalidEmailConfig). + Build() + utils.HttpResponse(c, 500, errorCode) return } emailClient.Send( diff --git a/service/auth/redirect.go b/service/auth/redirect.go index 01106a6..cb4e5a1 100644 --- a/service/auth/redirect.go +++ b/service/auth/redirect.go @@ -3,6 +3,7 @@ package auth import ( "net/url" "nixcn-cms/data" + "nixcn-cms/exception" "nixcn-cms/pkgs/authcode" "nixcn-cms/utils" @@ -14,19 +15,40 @@ import ( func Redirect(c *gin.Context) { clientId := c.Query("client_id") if clientId == "" { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRedirectEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } redirectUri := c.Query("redirect_uri") if redirectUri == "" { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRedirectEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } state := c.Query("state") if state == "" { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRedirectEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } @@ -35,7 +57,14 @@ func Redirect(c *gin.Context) { // Verify email token authCode, ok := authcode.VerifyAuthCode(code) if !ok { - utils.HttpResponse(c, 403, "", "invalid or expired token") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRedirectEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthRedirectTokenInvalid). + Build() + utils.HttpResponse(c, 403, errorCode) return } @@ -52,11 +81,25 @@ func Redirect(c *gin.Context) { user.Username = user.UserId.String() user.PermissionLevel = 10 if err := user.Create(); err != nil { - utils.HttpResponse(c, 500, "", "internal server error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRedirectEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInternal). + Build() + utils.HttpResponse(c, 500, errorCode) return } } else { - utils.HttpResponse(c, 500, "", "internal server error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRedirectEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInternal). + Build() + utils.HttpResponse(c, 500, errorCode) return } } @@ -64,25 +107,53 @@ func Redirect(c *gin.Context) { clientData := new(data.Client) client, err := clientData.GetClientByClientId(clientId) if err != nil { - utils.HttpResponse(c, 400, "", "client not found") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRedirectEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthRedirectClientNotFound). + Build() + utils.HttpResponse(c, 400, errorCode) return } err = client.ValidateRedirectURI(redirectUri) if err != nil { - utils.HttpResponse(c, 400, "", "redirect uri not match") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRedirectEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthRedirectUriMismatch). + Build() + utils.HttpResponse(c, 400, errorCode) return } newCode, err := authcode.NewAuthCode(clientId, authCode.Email) if err != nil { - utils.HttpResponse(c, 500, "", "internal server error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRedirectEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInternal). + Build() + utils.HttpResponse(c, 500, errorCode) return } url, err := url.Parse(redirectUri) if err != nil { - utils.HttpResponse(c, 400, "", "invalid redirect uri") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRedirectEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthRedirectInvalidUri). + Build() + utils.HttpResponse(c, 400, errorCode) return } query := url.Query() diff --git a/service/auth/refresh.go b/service/auth/refresh.go index 6851a5b..8ecd4b0 100644 --- a/service/auth/refresh.go +++ b/service/auth/refresh.go @@ -1,6 +1,7 @@ package auth import ( + "nixcn-cms/exception" "nixcn-cms/pkgs/authtoken" "nixcn-cms/utils" @@ -14,7 +15,14 @@ func Refresh(c *gin.Context) { } if err := c.ShouldBindJSON(&req); err != nil { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRefreshEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } @@ -24,13 +32,27 @@ func Refresh(c *gin.Context) { accessToken, err := JwtTool.RefreshAccessToken(req.RefreshToken) if err != nil { - utils.HttpResponse(c, 401, "", "invalid refresh token") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRefreshEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthRefreshInvalidToken). + Build() + utils.HttpResponse(c, 401, errorCode) return } refreshToken, err := JwtTool.RenewRefreshToken(req.RefreshToken) if err != nil { - utils.HttpResponse(c, 500, "", "error renew refresh token") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthRefreshEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthRefreshRenewFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } diff --git a/service/auth/token.go b/service/auth/token.go index c2d574a..2e00588 100644 --- a/service/auth/token.go +++ b/service/auth/token.go @@ -2,6 +2,7 @@ package auth import ( "nixcn-cms/data" + "nixcn-cms/exception" "nixcn-cms/pkgs/authcode" "nixcn-cms/pkgs/authtoken" "nixcn-cms/utils" @@ -19,20 +20,41 @@ func Token(c *gin.Context) { err := c.ShouldBindJSON(&req) if err != nil { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthTokenEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } authCode, ok := authcode.VerifyAuthCode(req.Code) if !ok { - utils.HttpResponse(c, 403, "", "invalid or expired token") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.AuthService). + SetEndpoint(exception.AuthTokenEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthTokenInvalidToken). + Build() + utils.HttpResponse(c, 403, errorCode) return } userData := new(data.User) user, err := userData.GetByEmail(authCode.Email) if err != nil { - utils.HttpResponse(c, 500, "", "internal server error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthTokenEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInternal). + Build() + utils.HttpResponse(c, 500, errorCode) return } @@ -42,7 +64,14 @@ func Token(c *gin.Context) { } accessToken, refreshToken, err := JwtTool.IssueTokens(authCode.ClientId, user.UserId) if err != nil { - utils.HttpResponse(c, 500, "", "error generating tokens") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.AuthService). + SetEndpoint(exception.AuthTokenEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.AuthTokenGenFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } diff --git a/service/event/checkin.go b/service/event/checkin.go index 9adbd01..ae72da4 100644 --- a/service/event/checkin.go +++ b/service/event/checkin.go @@ -2,6 +2,7 @@ package event import ( "nixcn-cms/data" + "nixcn-cms/exception" "nixcn-cms/utils" "time" @@ -13,31 +14,66 @@ func Checkin(c *gin.Context) { data := new(data.Attendance) userIdOrig, ok := c.Get("user_id") if !ok { - utils.HttpResponse(c, 403, "", "userid error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorMissingUserId). + Build() + utils.HttpResponse(c, 403, errorCode) return } userId, err := uuid.Parse(userIdOrig.(string)) if err != nil { - utils.HttpResponse(c, 500, "", "failed to parse uuid") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUuidParseFailed). + Build() + utils.HttpResponse(c, 500, errorCode) } // Get event id from query eventIdOrig, ok := c.GetQuery("event_id") if !ok { - utils.HttpResponse(c, 400, "", "undefinded event id") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } // Parse event id to uuid eventId, err := uuid.Parse(eventIdOrig) if err != nil { - utils.HttpResponse(c, 500, "", "error parsing string to uuid") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUuidParseFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } data.UserId = userId code, err := data.GenCheckinCode(eventId) if err != nil { - utils.HttpResponse(c, 500, "", "error generating code") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.EventCheckinGenCodeFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } @@ -56,7 +92,14 @@ func CheckinSubmit(c *gin.Context) { attendanceData := new(data.Attendance) err := attendanceData.VerifyCheckinCode(req.ChekinCode) if err != nil { - utils.HttpResponse(c, 400, "", "error verify checkin code") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinSubmitEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } @@ -66,23 +109,51 @@ func CheckinSubmit(c *gin.Context) { func CheckinQuery(c *gin.Context) { userIdOrig, ok := c.Get("user_id") if !ok { - utils.HttpResponse(c, 400, "", "userid error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinQueryEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorMissingUserId). + Build() + utils.HttpResponse(c, 400, errorCode) return } userId, err := uuid.Parse(userIdOrig.(string)) if err != nil { - utils.HttpResponse(c, 500, "", "failed to parse uuid") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinQueryEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUuidParseFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } eventIdOrig, ok := c.GetQuery("event_id") if !ok { - utils.HttpResponse(c, 400, "", "could not found event_id") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinQueryEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } eventId, err := uuid.Parse(eventIdOrig) if err != nil { - utils.HttpResponse(c, 400, "", "event_id is not valid") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinQueryEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } @@ -90,10 +161,24 @@ func CheckinQuery(c *gin.Context) { attendance, err := attendanceData.GetAttendance(userId, eventId) if err != nil { - utils.HttpResponse(c, 500, "", "database error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinQueryEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorDatabase). + Build() + utils.HttpResponse(c, 500, errorCode) return } else if attendance == nil { - utils.HttpResponse(c, 404, "", "event checkin record not found") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.EventService). + SetEndpoint(exception.EventCheckinQueryEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.EventCheckinQueryRecordNotFound). + Build() + utils.HttpResponse(c, 404, errorCode) return } else if attendance.CheckinAt.IsZero() { utils.HttpResponse(c, 200, "", "success", gin.H{"checkin_at": nil}) diff --git a/service/event/info.go b/service/event/info.go index 747ce1e..6109944 100644 --- a/service/event/info.go +++ b/service/event/info.go @@ -2,6 +2,7 @@ package event import ( "nixcn-cms/data" + "nixcn-cms/exception" "nixcn-cms/utils" "time" @@ -13,20 +14,41 @@ func Info(c *gin.Context) { eventData := new(data.Event) eventIdOrig, ok := c.GetQuery("event_id") if !ok { - utils.HttpResponse(c, 400, "", "undefinded event id") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.EventService). + SetEndpoint(exception.EventInfoEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } // Parse event id eventId, err := uuid.Parse(eventIdOrig) if err != nil { - utils.HttpResponse(c, 500, "", "error parsing string to uuid") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.EventService). + SetEndpoint(exception.EventInfoEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUuidParseFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } event, err := eventData.GetEventById(eventId) if err != nil { - utils.HttpResponse(c, 404, "", "event id not found") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.EventService). + SetEndpoint(exception.EventInfoEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.EventInfoNotFound). + Build() + utils.HttpResponse(c, 404, errorCode) return } diff --git a/service/user/full.go b/service/user/full.go index edd2106..cfadcb9 100644 --- a/service/user/full.go +++ b/service/user/full.go @@ -2,6 +2,7 @@ package user import ( "nixcn-cms/data" + "nixcn-cms/exception" "nixcn-cms/utils" "github.com/gin-gonic/gin" @@ -11,24 +12,52 @@ import ( func Full(c *gin.Context) { userIdOrig, ok := c.Get("user_id") if !ok { - utils.HttpResponse(c, 403, "", "userid error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.UserService). + SetEndpoint(exception.UserFullEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorMissingUserId). + Build() + utils.HttpResponse(c, 403, errorCode) return } userId, err := uuid.Parse(userIdOrig.(string)) if err != nil { - utils.HttpResponse(c, 500, "", "failed to parse uuid") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.UserService). + SetEndpoint(exception.UserFullEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUuidParseFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } userData, err := new(data.User).GetByUserId(userId) if err != nil { - utils.HttpResponse(c, 404, "", "user not found") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.UserService). + SetEndpoint(exception.UserFullEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUserNotFound). + Build() + utils.HttpResponse(c, 404, errorCode) return } users, err := userData.GetFullTable() if err != nil { - utils.HttpResponse(c, 500, "", "database error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.UserService). + SetEndpoint(exception.UserFullEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorDatabase). + Build() + utils.HttpResponse(c, 500, errorCode) return } diff --git a/service/user/info.go b/service/user/info.go index 17b88eb..c59de04 100644 --- a/service/user/info.go +++ b/service/user/info.go @@ -2,6 +2,7 @@ package user import ( "nixcn-cms/data" + "nixcn-cms/exception" "nixcn-cms/utils" "github.com/gin-gonic/gin" @@ -12,19 +13,40 @@ func Info(c *gin.Context) { userData := new(data.User) userIdOrig, ok := c.Get("user_id") if !ok { - utils.HttpResponse(c, 403, "", "userid error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.UserService). + SetEndpoint(exception.UserInfoEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorMissingUserId). + Build() + utils.HttpResponse(c, 403, errorCode) return } userId, err := uuid.Parse(userIdOrig.(string)) if err != nil { - utils.HttpResponse(c, 500, "", "failed to parse uuid") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.UserService). + SetEndpoint(exception.UserInfoEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUuidParseFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } // Get user from database user, err := userData.GetByUserId(userId) if err != nil { - utils.HttpResponse(c, 404, "", "user not found") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.UserService). + SetEndpoint(exception.UserInfoEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUserNotFound). + Build() + utils.HttpResponse(c, 404, errorCode) return } diff --git a/service/user/list.go b/service/user/list.go index eb9b717..1d2adcb 100644 --- a/service/user/list.go +++ b/service/user/list.go @@ -2,6 +2,7 @@ package user import ( "nixcn-cms/data" + "nixcn-cms/exception" "nixcn-cms/utils" "strconv" @@ -16,26 +17,54 @@ func List(c *gin.Context) { } offset, ok := c.GetQuery("offset") if !ok { - utils.HttpResponse(c, 400, "", "offset not found") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.UserService). + SetEndpoint(exception.UserListEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } // Parse string to int64 limitNum, err := strconv.ParseInt(limit, 10, 64) if err != nil { - utils.HttpResponse(c, 400, "", "parse string to int error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.UserService). + SetEndpoint(exception.UserListEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } offsetNum, err := strconv.ParseInt(offset, 10, 64) if err != nil { - utils.HttpResponse(c, 400, "", "parse string to int error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.UserService). + SetEndpoint(exception.UserListEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } // Get user list from search engine list, err := new(data.User).FastListUsers(limitNum, offsetNum) if err != nil { - utils.HttpResponse(c, 500, "", "failed list users from meilisearch") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.UserService). + SetEndpoint(exception.UserListEndpoint). + SetType(exception.ErrorTypeSpecific). + SetOriginal(exception.UserListMeilisearchFailed). + Build() + utils.HttpResponse(c, 500, errorCode) } userListResp := struct { diff --git a/service/user/update.go b/service/user/update.go index 95228ac..791bb30 100644 --- a/service/user/update.go +++ b/service/user/update.go @@ -3,6 +3,7 @@ package user import ( "net/url" "nixcn-cms/data" + "nixcn-cms/exception" "nixcn-cms/internal/cryptography" "nixcn-cms/utils" "unicode/utf8" @@ -15,26 +16,54 @@ func Update(c *gin.Context) { // New user model userIdOrig, ok := c.Get("user_id") if !ok { - utils.HttpResponse(c, 403, "", "userid error") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.UserService). + SetEndpoint(exception.UserUpdateEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorMissingUserId). + Build() + utils.HttpResponse(c, 403, errorCode) return } userId, err := uuid.Parse(userIdOrig.(string)) if err != nil { - utils.HttpResponse(c, 500, "", "failed to parse uuid") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusServer). + SetService(exception.UserService). + SetEndpoint(exception.UserUpdateEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUuidParseFailed). + Build() + utils.HttpResponse(c, 500, errorCode) return } var ReqInfo data.User err = c.ShouldBindJSON(&ReqInfo) if err != nil { - utils.HttpResponse(c, 400, "", "invilad request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.UserService). + SetEndpoint(exception.UserUpdateEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } // Get user info userData, err := new(data.User).GetByUserId(userId) if err != nil { - utils.HttpResponse(c, 500, "", "failed to find user") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusUser). + SetService(exception.UserService). + SetEndpoint(exception.UserUpdateEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorUserNotFound). + Build() + utils.HttpResponse(c, 500, errorCode) return } @@ -49,7 +78,14 @@ func Update(c *gin.Context) { if ReqInfo.Username != "" { if len(ReqInfo.Username) < 5 || len(ReqInfo.Username) >= 255 { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.UserService). + SetEndpoint(exception.UserUpdateEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } userData.Username = ReqInfo.Username @@ -57,7 +93,14 @@ func Update(c *gin.Context) { if ReqInfo.Nickname != "" { if utf8.RuneCountInString(ReqInfo.Nickname) > 24 { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.UserService). + SetEndpoint(exception.UserUpdateEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } userData.Nickname = ReqInfo.Nickname @@ -65,7 +108,14 @@ func Update(c *gin.Context) { if ReqInfo.Subtitle != "" { if utf8.RuneCountInString(ReqInfo.Subtitle) > 32 { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.UserService). + SetEndpoint(exception.UserUpdateEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } userData.Subtitle = ReqInfo.Subtitle @@ -74,7 +124,14 @@ func Update(c *gin.Context) { if ReqInfo.Avatar != "" { _, err := url.ParseRequestURI(ReqInfo.Avatar) if err != nil { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.UserService). + SetEndpoint(exception.UserUpdateEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } userData.Avatar = ReqInfo.Avatar @@ -82,7 +139,14 @@ func Update(c *gin.Context) { if ReqInfo.Bio != "" { if !cryptography.IsBase64Std(ReqInfo.Bio) { - utils.HttpResponse(c, 400, "", "invalid request") + errorCode := new(exception.Builder). + SetStatus(exception.ErrorStatusClient). + SetService(exception.UserService). + SetEndpoint(exception.UserUpdateEndpoint). + SetType(exception.ErrorTypeCommon). + SetOriginal(exception.CommonErrorInvalidInput). + Build() + utils.HttpResponse(c, 400, errorCode) return } userData.Bio = ReqInfo.Bio