diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go index 6375748086c..5a170980ddb 100644 --- a/routers/api/v1/admin/org.go +++ b/routers/api/v1/admin/org.go @@ -67,7 +67,7 @@ func CreateOrg(ctx *context.APIContext) { db.IsErrNameReserved(err) || db.IsErrNameCharsNotAllowed(err) || db.IsErrNamePatternNotAllowed(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index d7f10b75b0b..434eacee47f 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -40,7 +40,7 @@ func parseAuthSource(ctx *context.APIContext, u *user_model.User, sourceID int64 source, err := auth.GetSourceByID(ctx, sourceID) if err != nil { if auth.IsErrSourceNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -98,13 +98,13 @@ func CreateUser(ctx *context.APIContext) { if u.LoginType == auth.Plain { if len(form.Password) < setting.MinPasswordLength { err := errors.New("PasswordIsRequired") - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } if !password.IsComplexEnough(form.Password) { err := errors.New("PasswordComplexity") - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } @@ -112,7 +112,7 @@ func CreateUser(ctx *context.APIContext) { if password.IsErrIsPwnedRequest(err) { log.Error(err.Error()) } - ctx.APIError(http.StatusBadRequest, errors.New("PasswordPwned")) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(errors.New("PasswordPwned"))) return } } @@ -143,7 +143,7 @@ func CreateUser(ctx *context.APIContext) { user_model.IsErrEmailCharIsNotSupported(err) || user_model.IsErrEmailInvalid(err) || db.IsErrNamePatternNotAllowed(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -204,11 +204,11 @@ func EditUser(ctx *context.APIContext) { if err := user_service.UpdateAuth(ctx, ctx.ContextUser, authOpts); err != nil { switch { case errors.Is(err, password.ErrMinLength): - ctx.APIError(http.StatusBadRequest, fmt.Errorf("password must be at least %d characters", setting.MinPasswordLength)) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(fmt.Errorf("password must be at least %d characters", setting.MinPasswordLength))) case errors.Is(err, password.ErrComplexity): - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) case errors.Is(err, password.ErrIsPwned), password.IsErrIsPwnedRequest(err): - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) default: ctx.APIErrorInternal(err) } @@ -222,9 +222,9 @@ func EditUser(ctx *context.APIContext) { if !user_model.IsEmailDomainAllowed(*form.Email) { err = fmt.Errorf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", *form.Email) } - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) case user_model.IsErrEmailAlreadyUsed(err): - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) default: ctx.APIErrorInternal(err) } @@ -249,7 +249,7 @@ func EditUser(ctx *context.APIContext) { if err := user_service.UpdateUser(ctx, ctx.ContextUser, opts); err != nil { if user_model.IsErrDeleteLastAdminUser(err) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -289,13 +289,13 @@ func DeleteUser(ctx *context.APIContext) { // "$ref": "#/responses/validationError" if ctx.ContextUser.IsOrganization() { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name))) return } // admin should not delete themself if ctx.ContextUser.ID == ctx.Doer.ID { - ctx.APIError(http.StatusUnprocessableEntity, errors.New("you cannot delete yourself")) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(errors.New("you cannot delete yourself"))) return } @@ -304,7 +304,7 @@ func DeleteUser(ctx *context.APIContext) { org_model.IsErrUserHasOrgs(err) || packages_model.IsErrUserOwnPackages(err) || user_model.IsErrDeleteLastAdminUser(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -378,7 +378,7 @@ func DeleteUserPublicKey(ctx *context.APIContext) { if asymkey_model.IsErrKeyNotExist(err) { ctx.APIErrorNotFound() } else if asymkey_model.IsErrKeyAccessDenied(err) { - ctx.APIError(http.StatusForbidden, "You do not have access to this key") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("You do not have access to this key")) } else { ctx.APIErrorInternal(err) } @@ -475,7 +475,7 @@ func SearchUsers(ctx *context.APIContext) { if visibility, ok := api.VisibilityModes[visibilityParam]; ok { visible = []api.VisibleType{visibility} } else { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid visibility: \"%s\"", visibilityParam)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("Invalid visibility: \"%s\"", visibilityParam))) return } } @@ -551,7 +551,7 @@ func RenameUser(ctx *context.APIContext) { // "$ref": "#/responses/validationError" if ctx.ContextUser.IsOrganization() { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name))) return } @@ -560,7 +560,7 @@ func RenameUser(ctx *context.APIContext) { // Check if username has been changed if err := user_service.RenameUser(ctx, ctx.ContextUser, newName, ctx.Doer); err != nil { if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index eb5f52fd575..730bb4e3298 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -237,7 +237,7 @@ func doerNeedTwoFactorAuth(ctx gocontext.Context, doer *user_model.User) (bool, func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if ctx.Package.AccessMode < accessMode && !ctx.IsUserSiteAdmin() { - ctx.APIError(http.StatusForbidden, "user should have specific permission or be a site admin") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should have specific permission or be a site admin")) return } } @@ -258,39 +258,39 @@ func checkTokenPublicOnly() func(ctx *context.APIContext) { switch category { case auth_model.AccessTokenScopeCategoryRepository: if !ctx.TokenCanAccessRepo(ctx.Repo.Repository) { - ctx.APIError(http.StatusForbidden, "token scope is limited to public repos") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("token scope is limited to public repos")) return } case auth_model.AccessTokenScopeCategoryIssue: if !ctx.TokenCanAccessRepo(ctx.Repo.Repository) { - ctx.APIError(http.StatusForbidden, "token scope is limited to public issues") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("token scope is limited to public issues")) return } case auth_model.AccessTokenScopeCategoryOrganization: orgPrivate := ctx.Org.Organization != nil && !ctx.Org.Organization.Visibility.IsPublic() userOrgPrivate := ctx.ContextUser != nil && ctx.ContextUser.IsOrganization() && !ctx.ContextUser.Visibility.IsPublic() if orgPrivate || userOrgPrivate { - ctx.APIError(http.StatusForbidden, "token scope is limited to public orgs") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("token scope is limited to public orgs")) return } case auth_model.AccessTokenScopeCategoryUser: if ctx.ContextUser != nil && ctx.ContextUser.IsTokenAccessAllowed() && !ctx.ContextUser.Visibility.IsPublic() { - ctx.APIError(http.StatusForbidden, "token scope is limited to public users") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("token scope is limited to public users")) return } case auth_model.AccessTokenScopeCategoryActivityPub: if ctx.ContextUser != nil && ctx.ContextUser.IsTokenAccessAllowed() && !ctx.ContextUser.Visibility.IsPublic() { - ctx.APIError(http.StatusForbidden, "token scope is limited to public activitypub") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("token scope is limited to public activitypub")) return } case auth_model.AccessTokenScopeCategoryNotification: if !ctx.TokenCanAccessRepo(ctx.Repo.Repository) { - ctx.APIError(http.StatusForbidden, "token scope is limited to public notifications") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("token scope is limited to public notifications")) return } case auth_model.AccessTokenScopeCategoryPackage: if ctx.Package != nil && ctx.Package.Owner.Visibility.IsPrivate() { - ctx.APIError(http.StatusForbidden, "token scope is limited to public packages") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("token scope is limited to public packages")) return } } @@ -304,7 +304,7 @@ func rejectPublicOnly() func(ctx *context.APIContext) { return } - ctx.APIError(http.StatusForbidden, "this endpoint is not available for public-only tokens") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("this endpoint is not available for public-only tokens")) } } @@ -339,12 +339,12 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC requiredScopes := auth_model.GetRequiredScopes(requiredScopeLevel, requiredScopeCategories...) allow, err := scope.HasScope(requiredScopes...) if err != nil { - ctx.APIError(http.StatusForbidden, "checking scope failed: "+err.Error()) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("checking scope failed: "+err.Error())) return } if !allow { - ctx.APIError(http.StatusForbidden, fmt.Sprintf("token does not have at least one of required scope(s), required=%v, token scope=%v", requiredScopes, scope)) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(fmt.Sprintf("token does not have at least one of required scope(s), required=%v, token scope=%v", requiredScopes, scope))) return } @@ -353,7 +353,7 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC // check if scope only applies to public resources publicOnly, err := scope.PublicOnly() if err != nil { - ctx.APIError(http.StatusForbidden, "parsing public resource scope failed: "+err.Error()) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("parsing public resource scope failed: "+err.Error())) return } @@ -369,14 +369,14 @@ func reqToken() func(ctx *context.APIContext) { if ctx.IsSigned { return } - ctx.APIError(http.StatusUnauthorized, "token is required") + ctx.APIError(http.StatusUnauthorized, ctx.APIErrorMessage("token is required")) } } func reqExploreSignIn() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if (setting.Service.RequireSignInViewStrict || setting.Service.Explore.RequireSigninView) && !ctx.IsSigned { - ctx.APIError(http.StatusUnauthorized, "you must be signed in to search for users") + ctx.APIError(http.StatusUnauthorized, ctx.APIErrorMessage("you must be signed in to search for users")) } } } @@ -395,7 +395,7 @@ func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) { return } if !ctx.IsBasicAuth { - ctx.APIError(http.StatusUnauthorized, "auth required") + ctx.APIError(http.StatusUnauthorized, ctx.APIErrorMessage("auth required")) return } } @@ -405,7 +405,7 @@ func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) { func reqSiteAdmin() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserSiteAdmin() { - ctx.APIError(http.StatusForbidden, "user should be the site admin") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should be the site admin")) return } } @@ -415,7 +415,7 @@ func reqSiteAdmin() func(ctx *context.APIContext) { func reqOwner() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.Repo.Permission.IsOwner() && !ctx.IsUserSiteAdmin() { - ctx.APIError(http.StatusForbidden, "user should be the owner of the repo") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should be the owner of the repo")) return } } @@ -425,7 +425,7 @@ func reqOwner() func(ctx *context.APIContext) { func reqSelfOrAdmin() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserSiteAdmin() && ctx.ContextUser != ctx.Doer { - ctx.APIError(http.StatusForbidden, "doer should be the site admin or be same as the contextUser") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("doer should be the site admin or be same as the contextUser")) return } } @@ -435,7 +435,7 @@ func reqSelfOrAdmin() func(ctx *context.APIContext) { func reqAdmin() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserRepoAdmin() && !ctx.IsUserSiteAdmin() { - ctx.APIError(http.StatusForbidden, "user should be an owner or a collaborator with admin write of a repository") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should be an owner or a collaborator with admin write of a repository")) return } } @@ -445,7 +445,7 @@ func reqAdmin() func(ctx *context.APIContext) { func reqRepoWriter(unitTypes ...unit.Type) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserRepoWriter(unitTypes) && !ctx.IsUserRepoAdmin() && !ctx.IsUserSiteAdmin() { - ctx.APIError(http.StatusForbidden, "user should have a permission to write to a repo") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should have a permission to write to a repo")) return } } @@ -455,7 +455,7 @@ func reqRepoWriter(unitTypes ...unit.Type) func(ctx *context.APIContext) { func reqRepoReader(unitType unit.Type) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.Repo.Permission.CanRead(unitType) && !ctx.IsUserRepoAdmin() && !ctx.IsUserSiteAdmin() { - ctx.APIError(http.StatusForbidden, "user should have specific read permission or be a repo admin or a site admin") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should have specific read permission or be a repo admin or a site admin")) return } } @@ -465,7 +465,7 @@ func reqRepoReader(unitType unit.Type) func(ctx *context.APIContext) { func reqAnyRepoReader() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.Repo.Permission.HasAnyUnitAccess() && !ctx.IsUserSiteAdmin() { - ctx.APIError(http.StatusForbidden, "user should have any permission to read repository or permissions of site admin") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should have any permission to read repository or permissions of site admin")) return } } @@ -495,7 +495,7 @@ func reqOrgOwnership() func(ctx *context.APIContext) { return } else if !isOwner { if ctx.Org.Organization != nil { - ctx.APIError(http.StatusForbidden, "Must be an organization owner") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Must be an organization owner")) } else { ctx.APIErrorNotFound() } @@ -533,7 +533,7 @@ func reqTeamMembership() func(ctx *context.APIContext) { if err != nil { ctx.APIErrorInternal(err) } else if isOrgMember { - ctx.APIError(http.StatusForbidden, "Must be a team member") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Must be a team member")) } else { ctx.APIErrorNotFound() } @@ -565,7 +565,7 @@ func reqOrgMembership() func(ctx *context.APIContext) { return } else if !isMember { if ctx.Org.Organization != nil { - ctx.APIError(http.StatusForbidden, "Must be an organization member") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Must be an organization member")) } else { ctx.APIErrorNotFound() } @@ -577,7 +577,7 @@ func reqOrgMembership() func(ctx *context.APIContext) { func reqGitHook() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.Doer.CanEditGitHook() { - ctx.APIError(http.StatusForbidden, "must be allowed to edit Git hooks") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("must be allowed to edit Git hooks")) return } } @@ -587,7 +587,7 @@ func reqGitHook() func(ctx *context.APIContext) { func reqWebhooksEnabled() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if setting.DisableWebhooks { - ctx.APIError(http.StatusForbidden, "webhooks disabled by administrator") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("webhooks disabled by administrator")) return } } @@ -597,7 +597,7 @@ func reqWebhooksEnabled() func(ctx *context.APIContext) { func reqStarsEnabled() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if setting.Repository.DisableStars { - ctx.APIError(http.StatusForbidden, "stars disabled by administrator") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("stars disabled by administrator")) return } } @@ -734,14 +734,14 @@ func mustEnableWiki(ctx *context.APIContext) { // FIXME: for consistency, maybe most mustNotBeArchived checks should be replaced with mustEnableEditor func mustNotBeArchived(ctx *context.APIContext) { if ctx.Repo.Repository.IsArchived { - ctx.APIError(http.StatusLocked, fmt.Errorf("%s is archived", ctx.Repo.Repository.FullName())) + ctx.APIError(http.StatusLocked, ctx.APIErrorMessage(fmt.Errorf("%s is archived", ctx.Repo.Repository.FullName()))) return } } func mustEnableEditor(ctx *context.APIContext) { if !ctx.Repo.Repository.CanEnableEditor() { - ctx.APIError(http.StatusLocked, fmt.Errorf("%s is not allowed to edit", ctx.Repo.Repository.FullName())) + ctx.APIError(http.StatusLocked, ctx.APIErrorMessage(fmt.Errorf("%s is not allowed to edit", ctx.Repo.Repository.FullName()))) return } } @@ -759,7 +759,7 @@ func bind[T any](_ T) any { theObj := new(T) // create a new form obj for every request but not use obj directly errs := binding.Bind(ctx.Req, theObj) if len(errs) > 0 { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("%s: %s", errs[0].FieldNames, errs[0].Error())) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Sprintf("%s: %s", errs[0].FieldNames, errs[0].Error()))) return } web.SetForm(ctx, theObj) @@ -785,7 +785,7 @@ func apiAuth(authMethod auth.Method) func(*context.APIContext) { if err != nil { msg, ok := auth.ErrAsUserAuthMessage(err) msg = util.Iif(ok, msg, "invalid username, password or token") - ctx.APIError(http.StatusUnauthorized, msg) + ctx.APIError(http.StatusUnauthorized, ctx.APIErrorMessage(msg)) return } ctx.Doer = ar.Doer diff --git a/routers/api/v1/notify/notifications.go b/routers/api/v1/notify/notifications.go index 92aae46a784..5237e4cef15 100644 --- a/routers/api/v1/notify/notifications.go +++ b/routers/api/v1/notify/notifications.go @@ -28,7 +28,7 @@ func NewAvailable(ctx *context.APIContext) { Status: []activities_model.NotificationStatus{activities_model.NotificationStatusUnread}, }) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } @@ -38,7 +38,7 @@ func NewAvailable(ctx *context.APIContext) { func getFindNotificationOptions(ctx *context.APIContext) *activities_model.FindNotificationOptions { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return nil } opts := &activities_model.FindNotificationOptions{ diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go index 16996907508..42e11b123ad 100644 --- a/routers/api/v1/notify/repo.go +++ b/routers/api/v1/notify/repo.go @@ -183,7 +183,7 @@ func ReadRepoNotifications(ctx *context.APIContext) { if len(qLastRead) > 0 { tmpLastRead, err := time.Parse(time.RFC3339, qLastRead) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } if !tmpLastRead.IsZero() { diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go index 2b8c91169f8..07c5f4b8a0f 100644 --- a/routers/api/v1/notify/threads.go +++ b/routers/api/v1/notify/threads.go @@ -104,14 +104,14 @@ func getThread(ctx *context.APIContext) *activities_model.Notification { n, err := activities_model.GetNotificationByID(ctx, ctx.PathParamInt64("id")) if err != nil { if db.IsErrNotExist(err) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } return nil } if n.UserID != ctx.Doer.ID && !ctx.Doer.IsAdmin { - ctx.APIError(http.StatusForbidden, fmt.Errorf("only user itself and admin are allowed to read/change this thread %d", n.ID)) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(fmt.Errorf("only user itself and admin are allowed to read/change this thread %d", n.ID))) return nil } return n diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go index 2e54eb178d4..43b6e249706 100644 --- a/routers/api/v1/notify/user.go +++ b/routers/api/v1/notify/user.go @@ -134,7 +134,7 @@ func ReadNotifications(ctx *context.APIContext) { if len(qLastRead) > 0 { tmpLastRead, err := time.Parse(time.RFC3339, qLastRead) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } if !tmpLastRead.IsZero() { diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go index d63a134bd55..b8d5083a46b 100644 --- a/routers/api/v1/org/action.go +++ b/routers/api/v1/org/action.go @@ -111,9 +111,9 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) { _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname"), opt.Data, opt.Description) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -158,9 +158,9 @@ func (Action) DeleteSecret(ctx *context.APIContext) { err := secret_service.DeleteSecretByName(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname")) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -277,7 +277,7 @@ func (Action) GetVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -327,9 +327,9 @@ func (Action) DeleteVariable(ctx *context.APIContext) { if err := actions_service.DeleteVariableByName(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("variablename")); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -387,13 +387,13 @@ func (Action) CreateVariable(ctx *context.APIContext) { return } if v != nil && v.ID > 0 { - ctx.APIError(http.StatusConflict, util.NewAlreadyExistErrorf("variable name %s already exists", variableName)) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(util.NewAlreadyExistErrorf("variable name %s already exists", variableName))) return } if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value, opt.Description); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -445,7 +445,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -462,7 +462,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) { if _, err := actions_service.UpdateVariableNameData(ctx, v); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/org/avatar.go b/routers/api/v1/org/avatar.go index 38b0655bea9..041246bcfa7 100644 --- a/routers/api/v1/org/avatar.go +++ b/routers/api/v1/org/avatar.go @@ -39,7 +39,7 @@ func UpdateAvatar(ctx *context.APIContext) { content, err := base64.StdEncoding.DecodeString(form.Image) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go index 4c3365e6a6d..563e030ef22 100644 --- a/routers/api/v1/org/label.go +++ b/routers/api/v1/org/label.go @@ -90,7 +90,7 @@ func CreateLabel(ctx *context.APIContext) { form.Color = strings.Trim(form.Color, " ") color, err := label.NormalizeColor(form.Color) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } form.Color = color @@ -209,7 +209,7 @@ func EditLabel(ctx *context.APIContext) { if form.Color != nil { color, err := label.NormalizeColor(*form.Color) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } l.Color = color diff --git a/routers/api/v1/org/member.go b/routers/api/v1/org/member.go index 957544d1047..3647ecef54a 100644 --- a/routers/api/v1/org/member.go +++ b/routers/api/v1/org/member.go @@ -221,9 +221,9 @@ func checkCanChangeOrgUserStatus(ctx *context.APIContext, targetUser *user_model // allow org owners to change status of members isOwner, err := ctx.Org.Organization.IsOwnedBy(ctx, ctx.Doer.ID) if err != nil { - ctx.APIError(http.StatusInternalServerError, err) + ctx.APIError(http.StatusInternalServerError, ctx.APIErrorMessage(err)) } else if !isOwner { - ctx.APIError(http.StatusForbidden, "Cannot change member visibility") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Cannot change member visibility")) } } diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index 87e847d6421..e88a94207ff 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -256,7 +256,7 @@ func Create(ctx *context.APIContext) { // "$ref": "#/responses/validationError" form := web.GetForm(ctx).(*api.CreateOrgOption) if !ctx.Doer.CanCreateOrganization() { - ctx.APIError(http.StatusForbidden, nil) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(nil)) return } @@ -282,7 +282,7 @@ func Create(ctx *context.APIContext) { db.IsErrNameReserved(err) || db.IsErrNameCharsNotAllowed(err) || db.IsErrNamePatternNotAllowed(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -355,7 +355,7 @@ func Rename(ctx *context.APIContext) { orgUser := ctx.Org.Organization.AsUser() if err := user_service.RenameUser(ctx, orgUser, form.NewName, ctx.Doer); err != nil { if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -394,7 +394,7 @@ func Edit(ctx *context.APIContext) { if err := org.UpdateOrgEmailAddress(ctx, ctx.Org.Organization, form.Email); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index d8acc767c58..e63f6273dd9 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -236,7 +236,7 @@ func CreateTeam(ctx *context.APIContext) { if err := org_service.NewTeam(ctx, team); err != nil { if organization.IsErrTeamAlreadyExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -490,7 +490,7 @@ func AddTeamMember(ctx *context.APIContext) { } if err := org_service.AddTeamMember(ctx, ctx.Org.Team, u); err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -691,7 +691,7 @@ func AddTeamRepository(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if access < perm.AccessModeAdmin { - ctx.APIError(http.StatusForbidden, "Must have admin-level access to the repository") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Must have admin-level access to the repository")) return } if err := repo_service.TeamAddRepository(ctx, ctx.Org.Team, repo); err != nil { @@ -743,7 +743,7 @@ func RemoveTeamRepository(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if access < perm.AccessModeAdmin { - ctx.APIError(http.StatusForbidden, "Must have admin-level access to the repository") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Must have admin-level access to the repository")) return } if err := repo_service.RemoveRepositoryFromTeam(ctx, ctx.Org.Team, repo.ID); err != nil { diff --git a/routers/api/v1/packages/package.go b/routers/api/v1/packages/package.go index 6b01023ef91..ee18d196758 100644 --- a/routers/api/v1/packages/package.go +++ b/routers/api/v1/packages/package.go @@ -329,7 +329,7 @@ func GetLatestPackageVersion(ctx *context.APIContext) { return } if len(pvs) == 0 { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) return } @@ -383,7 +383,7 @@ func LinkPackage(ctx *context.APIContext) { pkg, err := packages.GetPackageByName(ctx, ctx.ContextUser.ID, packages.Type(ctx.PathParam("type")), ctx.PathParam("name")) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -393,7 +393,7 @@ func LinkPackage(ctx *context.APIContext) { repo, err := repo_model.GetRepositoryByName(ctx, ctx.ContextUser.ID, ctx.PathParam("repo_name")) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -404,9 +404,9 @@ func LinkPackage(ctx *context.APIContext) { if err != nil { switch { case errors.Is(err, util.ErrInvalidArgument): - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) case errors.Is(err, util.ErrPermissionDenied): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) default: ctx.APIErrorInternal(err) } @@ -445,7 +445,7 @@ func UnlinkPackage(ctx *context.APIContext) { pkg, err := packages.GetPackageByName(ctx, ctx.ContextUser.ID, packages.Type(ctx.PathParam("type")), ctx.PathParam("name")) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -456,9 +456,9 @@ func UnlinkPackage(ctx *context.APIContext) { if err != nil { switch { case errors.Is(err, util.ErrPermissionDenied): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) case errors.Is(err, util.ErrInvalidArgument): - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) default: ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 169ed4b68ec..ebd4d21bf52 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -141,9 +141,9 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) { _, created, err := secret_service.CreateOrUpdateSecret(ctx, 0, repo.ID, ctx.PathParam("secretname"), opt.Data, opt.Description) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -195,9 +195,9 @@ func (Action) DeleteSecret(ctx *context.APIContext) { err := secret_service.DeleteSecretByName(ctx, 0, repo.ID, ctx.PathParam("secretname")) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -243,7 +243,7 @@ func (Action) GetVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -298,9 +298,9 @@ func (Action) DeleteVariable(ctx *context.APIContext) { if err := actions_service.DeleteVariableByName(ctx, 0, ctx.Repo.Repository.ID, ctx.PathParam("variablename")); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -361,13 +361,13 @@ func (Action) CreateVariable(ctx *context.APIContext) { return } if v != nil && v.ID > 0 { - ctx.APIError(http.StatusConflict, util.NewAlreadyExistErrorf("variable name %s already exists", variableName)) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(util.NewAlreadyExistErrorf("variable name %s already exists", variableName))) return } if _, err := actions_service.CreateVariable(ctx, 0, repoID, variableName, opt.Value, opt.Description); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -422,7 +422,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -439,7 +439,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) { if _, err := actions_service.UpdateVariableNameData(ctx, v); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -957,7 +957,7 @@ func ActionsGetWorkflow(ctx *context.APIContext) { workflow, err := convert.GetActionWorkflow(ctx, ctx.Repo.GitRepo, ctx.Repo.Repository, workflowID) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -1005,7 +1005,7 @@ func ActionsDisableWorkflow(ctx *context.APIContext) { err := actions_service.EnableOrDisableWorkflow(ctx, workflowID, false) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -1062,7 +1062,7 @@ func ActionsDispatchWorkflow(ctx *context.APIContext) { workflowID := ctx.PathParam("workflow_id") opt := web.GetForm(ctx).(*api.CreateActionWorkflowDispatch) if opt.Ref == "" { - ctx.APIError(http.StatusUnprocessableEntity, util.NewInvalidArgumentErrorf("ref is required parameter")) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(util.NewInvalidArgumentErrorf("ref is required parameter"))) return } @@ -1088,11 +1088,11 @@ func ActionsDispatchWorkflow(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrPermissionDenied) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -1151,7 +1151,7 @@ func ActionsEnableWorkflow(ctx *context.APIContext) { err := actions_service.EnableOrDisableWorkflow(ctx, workflowID, true) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -1490,13 +1490,13 @@ func RerunWorkflowJob(ctx *context.APIContext) { func handleWorkflowRerunError(ctx *context.APIContext, err error) { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } else if errors.Is(err, util.ErrAlreadyExist) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) return } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1560,7 +1560,7 @@ func ListWorkflowRunJobs(ctx *context.APIContext) { // Avoid the list all jobs functionality for this api route to be used with a runID == 0. if runID <= 0 { - ctx.APIError(http.StatusBadRequest, util.NewInvalidArgumentErrorf("runID must be a positive integer")) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(util.NewInvalidArgumentErrorf("runID must be a positive integer"))) return } @@ -1790,7 +1790,7 @@ func DeleteActionRun(ctx *context.APIContext) { } if !run.Status.IsDone() { - ctx.APIError(http.StatusBadRequest, "this workflow run is not done") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("this workflow run is not done")) return } @@ -1908,7 +1908,7 @@ func GetArtifact(ctx *context.APIContext) { return } // v3 not supported due to not having one unique id - ctx.APIError(http.StatusNotFound, "Artifact not found") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("Artifact not found")) } // DeleteArtifact Deletes a specific artifact for a workflow run. @@ -1956,7 +1956,7 @@ func DeleteArtifact(ctx *context.APIContext) { return } // v3 not supported due to not having one unique id - ctx.APIError(http.StatusNotFound, "Artifact not found") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("Artifact not found")) } func buildSignature(endp string, expires, artifactID int64) []byte { @@ -2012,7 +2012,7 @@ func DownloadArtifact(ctx *context.APIContext) { // if artifacts status is not uploaded-confirmed, treat it as not found if art.Status == actions_model.ArtifactStatusExpired { - ctx.APIError(http.StatusNotFound, "Artifact has expired") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("Artifact has expired")) return } @@ -2030,7 +2030,7 @@ func DownloadArtifact(ctx *context.APIContext) { return } // v3 not supported due to not having one unique id - ctx.APIError(http.StatusNotFound, "Artifact not found") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("Artifact not found")) } // DownloadArtifactRaw Downloads a specific artifact for a workflow run directly. @@ -2057,18 +2057,18 @@ func DownloadArtifactRaw(ctx *context.APIContext) { expectedSig := buildSignature(buildDownloadRawEndpoint(repo, art.ID), expires, art.ID) if !hmac.Equal(sigBytes, expectedSig) { - ctx.APIError(http.StatusUnauthorized, "Error unauthorized") + ctx.APIError(http.StatusUnauthorized, ctx.APIErrorMessage("Error unauthorized")) return } t := time.Unix(expires, 0) if t.Before(time.Now()) { - ctx.APIError(http.StatusUnauthorized, "Error link expired") + ctx.APIError(http.StatusUnauthorized, ctx.APIErrorMessage("Error link expired")) return } // if artifacts status is not uploaded-confirmed, treat it as not found if art.Status == actions_model.ArtifactStatusExpired { - ctx.APIError(http.StatusNotFound, "Artifact has expired") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("Artifact has expired")) return } if actions_service.IsArtifactV4(art) { @@ -2080,7 +2080,7 @@ func DownloadArtifactRaw(ctx *context.APIContext) { return } // v3 not supported due to not having one unique id - ctx.APIError(http.StatusNotFound, "artifact not found") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("artifact not found")) } // Try to get the artifact by ID and check access @@ -2097,7 +2097,7 @@ func getArtifactByPathParam(ctx *context.APIContext, repo *repo_model.Repository if !ok || art.RepoID != repo.ID || art.Status != actions_model.ArtifactStatusUploadConfirmed && art.Status != actions_model.ArtifactStatusExpired { - ctx.APIError(http.StatusNotFound, "artifact not found") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("artifact not found")) return nil } return art diff --git a/routers/api/v1/repo/avatar.go b/routers/api/v1/repo/avatar.go index b3d52e16634..889ad1c7378 100644 --- a/routers/api/v1/repo/avatar.go +++ b/routers/api/v1/repo/avatar.go @@ -44,7 +44,7 @@ func UpdateAvatar(ctx *context.APIContext) { content, err := base64.StdEncoding.DecodeString(form.Image) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } diff --git a/routers/api/v1/repo/blob.go b/routers/api/v1/repo/blob.go index cd731b0d787..64d56110f85 100644 --- a/routers/api/v1/repo/blob.go +++ b/routers/api/v1/repo/blob.go @@ -43,12 +43,12 @@ func GetBlob(ctx *context.APIContext) { sha := ctx.PathParam("sha") if len(sha) == 0 { - ctx.APIError(http.StatusBadRequest, "sha not provided") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("sha not provided")) return } if blob, err := files_service.GetBlobBySHA(ctx.Repo.Repository, ctx.Repo.GitRepo, sha); err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.JSON(http.StatusOK, blob) } diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 3afdf9694d1..674528accf7 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -122,12 +122,12 @@ func DeleteBranch(ctx *context.APIContext) { // "423": // "$ref": "#/responses/repoArchivedError" if ctx.Repo.Repository.IsEmpty { - ctx.APIError(http.StatusNotFound, "Git Repository is empty.") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("Git Repository is empty.")) return } if ctx.Repo.Repository.IsMirror { - ctx.APIError(http.StatusForbidden, "Git Repository is a mirror.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Git Repository is a mirror.")) return } @@ -155,9 +155,9 @@ func DeleteBranch(ctx *context.APIContext) { case git.IsErrBranchNotExist(err): ctx.APIErrorNotFound(err) case errors.Is(err, repo_service.ErrBranchIsDefault): - ctx.APIError(http.StatusForbidden, errors.New("can not delete default or pull request target branch")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("can not delete default or pull request target branch"))) case errors.Is(err, git_model.ErrBranchIsProtected): - ctx.APIError(http.StatusForbidden, errors.New("branch protected")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("branch protected"))) default: ctx.APIErrorInternal(err) } @@ -204,12 +204,12 @@ func CreateBranch(ctx *context.APIContext) { // "$ref": "#/responses/repoArchivedError" if ctx.Repo.Repository.IsEmpty { - ctx.APIError(http.StatusNotFound, "Git Repository is empty.") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("Git Repository is empty.")) return } if ctx.Repo.Repository.IsMirror { - ctx.APIError(http.StatusForbidden, "Git Repository is a mirror.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Git Repository is a mirror.")) return } @@ -232,7 +232,7 @@ func CreateBranch(ctx *context.APIContext) { return } } else { - ctx.APIError(http.StatusNotFound, "The old branch does not exist") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("The old branch does not exist")) return } } else { @@ -246,13 +246,13 @@ func CreateBranch(ctx *context.APIContext) { err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, oldCommit.ID.String(), opt.BranchName) if err != nil { if git_model.IsErrBranchNotExist(err) { - ctx.APIError(http.StatusNotFound, "The old branch does not exist") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("The old branch does not exist")) } else if release_service.IsErrTagAlreadyExists(err) { - ctx.APIError(http.StatusConflict, "The branch with the same tag already exists.") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("The branch with the same tag already exists.")) } else if git_model.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) { - ctx.APIError(http.StatusConflict, "The branch already exists.") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("The branch already exists.")) } else if git_model.IsErrBranchNameConflict(err) { - ctx.APIError(http.StatusConflict, "The branch with the same name already exists.") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("The branch with the same name already exists.")) } else { ctx.APIErrorInternal(err) } @@ -433,12 +433,12 @@ func UpdateBranch(ctx *context.APIContext) { repo := ctx.Repo.Repository if repo.IsEmpty { - ctx.APIError(http.StatusNotFound, "Git Repository is empty.") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("Git Repository is empty.")) return } if repo.IsMirror { - ctx.APIError(http.StatusForbidden, "Git Repository is a mirror.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Git Repository is a mirror.")) return } @@ -448,10 +448,10 @@ func UpdateBranch(ctx *context.APIContext) { case git_model.IsErrBranchNotExist(err): ctx.APIErrorNotFound(err) case errors.Is(err, util.ErrInvalidArgument): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) case git.IsErrPushRejected(err): rej := err.(*git.ErrPushRejected) - ctx.APIError(http.StatusForbidden, rej.Message) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(rej.Message)) default: ctx.APIErrorInternal(err) } @@ -506,12 +506,12 @@ func RenameBranch(ctx *context.APIContext) { repo := ctx.Repo.Repository if repo.IsEmpty { - ctx.APIError(http.StatusNotFound, "Git Repository is empty.") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("Git Repository is empty.")) return } if repo.IsMirror { - ctx.APIError(http.StatusForbidden, "Git Repository is a mirror.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Git Repository is a mirror.")) return } @@ -519,20 +519,20 @@ func RenameBranch(ctx *context.APIContext) { if err != nil { switch { case repo_model.IsErrUserDoesNotHaveAccessToRepo(err): - ctx.APIError(http.StatusForbidden, "User must be a repo or site admin to rename default or protected branches.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("User must be a repo or site admin to rename default or protected branches.")) case errors.Is(err, git_model.ErrBranchIsProtected): - ctx.APIError(http.StatusForbidden, "Failed to rename branch due to branch protection rules.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Failed to rename branch due to branch protection rules.")) default: ctx.APIErrorInternal(err) } return } if msg == "target_exist" { - ctx.APIError(http.StatusUnprocessableEntity, "Cannot rename a branch using the same name or rename to a branch that already exists.") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Cannot rename a branch using the same name or rename to a branch that already exists.")) return } if msg == "from_not_exist" { - ctx.APIError(http.StatusNotFound, "Branch doesn't exist.") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("Branch doesn't exist.")) return } @@ -663,7 +663,7 @@ func CreateBranchProtection(ctx *context.APIContext) { ruleName = form.BranchName //nolint:staticcheck // deprecated field } if len(ruleName) == 0 { - ctx.APIError(http.StatusBadRequest, "both rule_name and branch_name are empty") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("both rule_name and branch_name are empty")) return } @@ -672,7 +672,7 @@ func CreateBranchProtection(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if protectBranch != nil { - ctx.APIError(http.StatusForbidden, "Branch protection already exist") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Branch protection already exist")) return } @@ -684,7 +684,7 @@ func CreateBranchProtection(ctx *context.APIContext) { whitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.PushWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -693,7 +693,7 @@ func CreateBranchProtection(ctx *context.APIContext) { forcePushAllowlistUsers, err := user_model.GetUserIDsByNames(ctx, form.ForcePushAllowlistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -702,7 +702,7 @@ func CreateBranchProtection(ctx *context.APIContext) { mergeWhitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.MergeWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -711,7 +711,7 @@ func CreateBranchProtection(ctx *context.APIContext) { approvalsWhitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.ApprovalsWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -722,7 +722,7 @@ func CreateBranchProtection(ctx *context.APIContext) { bypassAllowlistUsers, err = user_model.GetUserIDsByNames(ctx, form.BypassAllowlistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -734,7 +734,7 @@ func CreateBranchProtection(ctx *context.APIContext) { whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.PushWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -743,7 +743,7 @@ func CreateBranchProtection(ctx *context.APIContext) { forcePushAllowlistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.ForcePushAllowlistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -752,7 +752,7 @@ func CreateBranchProtection(ctx *context.APIContext) { mergeWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.MergeWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -761,7 +761,7 @@ func CreateBranchProtection(ctx *context.APIContext) { approvalsWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.ApprovalsWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -771,7 +771,7 @@ func CreateBranchProtection(ctx *context.APIContext) { bypassAllowlistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.BypassAllowlistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -999,7 +999,7 @@ func EditBranchProtection(ctx *context.APIContext) { whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.PushWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1012,7 +1012,7 @@ func EditBranchProtection(ctx *context.APIContext) { forcePushAllowlistUsers, err = user_model.GetUserIDsByNames(ctx, form.ForcePushAllowlistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1025,7 +1025,7 @@ func EditBranchProtection(ctx *context.APIContext) { mergeWhitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.MergeWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1038,7 +1038,7 @@ func EditBranchProtection(ctx *context.APIContext) { approvalsWhitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.ApprovalsWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1051,7 +1051,7 @@ func EditBranchProtection(ctx *context.APIContext) { bypassAllowlistUsers, err = user_model.GetUserIDsByNames(ctx, form.BypassAllowlistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1067,7 +1067,7 @@ func EditBranchProtection(ctx *context.APIContext) { whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.PushWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1080,7 +1080,7 @@ func EditBranchProtection(ctx *context.APIContext) { forcePushAllowlistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.ForcePushAllowlistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1093,7 +1093,7 @@ func EditBranchProtection(ctx *context.APIContext) { mergeWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.MergeWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1106,7 +1106,7 @@ func EditBranchProtection(ctx *context.APIContext) { approvalsWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.ApprovalsWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1119,7 +1119,7 @@ func EditBranchProtection(ctx *context.APIContext) { bypassAllowlistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.BypassAllowlistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1331,10 +1331,10 @@ func MergeUpstream(ctx *context.APIContext) { mergeStyle, err := repo_service.MergeUpstream(ctx, ctx.Doer, ctx.Repo.Repository, form.Branch, form.FfOnly) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index b7938cb516d..974fd1ae844 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -107,7 +107,7 @@ func IsCollaborator(ctx *context.APIContext) { user, err := user_model.GetUserByName(ctx, ctx.PathParam("collaborator")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -167,7 +167,7 @@ func AddOrUpdateCollaborator(ctx *context.APIContext) { collaborator, err := user_model.GetUserByName(ctx, ctx.PathParam("collaborator")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -186,7 +186,7 @@ func AddOrUpdateCollaborator(ctx *context.APIContext) { if err := repo_service.AddOrUpdateCollaborator(ctx, ctx.Repo.Repository, collaborator, p); err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -230,7 +230,7 @@ func DeleteCollaborator(ctx *context.APIContext) { collaborator, err := user_model.GetUserByName(ctx, ctx.PathParam("collaborator")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -277,14 +277,14 @@ func GetRepoPermissions(ctx *context.APIContext) { collaboratorUsername := ctx.PathParam("collaborator") if !ctx.Doer.IsAdmin && !strings.EqualFold(ctx.Doer.LowerName, collaboratorUsername) && !ctx.IsUserRepoAdmin() { - ctx.APIError(http.StatusForbidden, "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own")) return } collaborator, err := user_model.GetUserByName(ctx, collaboratorUsername) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -326,7 +326,7 @@ func GetReviewers(ctx *context.APIContext) { canChooseReviewer := issue_service.CanDoerChangeReviewRequests(ctx, ctx.Doer, ctx.Repo.Repository, 0) if !canChooseReviewer { - ctx.APIError(http.StatusForbidden, errors.New("doer has no permission to get reviewers")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("doer has no permission to get reviewers"))) return } diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 620ee037006..f9957dd7f74 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -66,7 +66,7 @@ func GetSingleCommit(ctx *context.APIContext) { sha := ctx.PathParam("sha") if !git.IsValidRefPattern(sha) { - ctx.APIError(http.StatusUnprocessableEntity, "no valid ref or sha: "+sha) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("no valid ref or sha: "+sha)) return } @@ -166,13 +166,13 @@ func GetAllCommits(ctx *context.APIContext) { // Validate since/until as ISO 8601 (RFC3339) if since != "" { if _, err := time.Parse(time.RFC3339, since); err != nil { - ctx.APIError(http.StatusUnprocessableEntity, "invalid 'since' format, expected ISO 8601 (RFC3339)") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("invalid 'since' format, expected ISO 8601 (RFC3339)")) return } } if until != "" { if _, err := time.Parse(time.RFC3339, until); err != nil { - ctx.APIError(http.StatusUnprocessableEntity, "invalid 'until' format, expected ISO 8601 (RFC3339)") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("invalid 'until' format, expected ISO 8601 (RFC3339)")) return } } @@ -383,7 +383,7 @@ func GetCommitPullRequest(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByMergedCommit(ctx, ctx.Repo.Repository.ID, ctx.PathParam("sha")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/download.go b/routers/api/v1/repo/download.go index d9470d143ea..12f11c1ab31 100644 --- a/routers/api/v1/repo/download.go +++ b/routers/api/v1/repo/download.go @@ -17,9 +17,9 @@ func serveRepoArchive(ctx *context.APIContext, reqFileName string, paths []strin aReq, err := archiver_service.NewRequest(ctx.Repo.Repository, ctx.Repo.GitRepo, reqFileName, paths) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -28,7 +28,7 @@ func serveRepoArchive(ctx *context.APIContext, reqFileName string, paths []strin err = archiver_service.ServeRepoArchive(ctx.Base, aReq) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -47,7 +47,7 @@ func DownloadArchive(ctx *context.APIContext) { case "bundle": tp = repo_model.ArchiveBundle default: - ctx.APIError(http.StatusBadRequest, "Unknown archive type: "+ballType) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Unknown archive type: "+ballType)) return } serveRepoArchive(ctx, ctx.PathParam("*")+"."+tp.String(), ctx.FormStrings("path")) diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 5f0659dc818..350a3465d1a 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -331,7 +331,7 @@ func ReqChangeRepoFileOptionsAndCheck(ctx *context.APIContext) { commonOpts.BranchName = util.IfZero(commonOpts.BranchName, ctx.Repo.Repository.DefaultBranch) commonOpts.NewBranchName = util.IfZero(commonOpts.NewBranchName, commonOpts.BranchName) if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, commonOpts.NewBranchName) && !ctx.IsUserSiteAdmin() { - ctx.APIError(http.StatusForbidden, "user should have a permission to write to the target branch") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should have a permission to write to the target branch")) return } changeFileOpts := &files_service.ChangeRepoFilesOptions{ @@ -409,7 +409,7 @@ func ChangeFiles(ctx *context.APIContext) { for _, file := range apiOpts.Files { contentReader, err := base64Reader(file.ContentBase64) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } // FIXME: ChangeFileOperation.SHA is NOT required for update or delete if last commit is provided in the options @@ -483,7 +483,7 @@ func CreateFile(ctx *context.APIContext) { } contentReader, err := base64Reader(apiOpts.ContentBase64) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } @@ -554,7 +554,7 @@ func UpdateFile(ctx *context.APIContext) { } contentReader, err := base64Reader(apiOpts.ContentBase64) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } willCreate := apiOpts.SHA == "" @@ -580,21 +580,21 @@ func UpdateFile(ctx *context.APIContext) { func handleChangeRepoFilesError(ctx *context.APIContext, err error) { if git.IsErrPushRejected(err) { err := err.(*git.ErrPushRejected) - ctx.APIError(http.StatusForbidden, err.Message) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err.Message)) return } if files_service.IsErrUserCannotCommit(err) || pull_service.IsErrFilePathProtected(err) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) return } if git_model.IsErrBranchAlreadyExists(err) || files_service.IsErrFilenameInvalid(err) || pull_service.IsErrSHADoesNotMatch(err) || files_service.IsErrFilePathInvalid(err) || files_service.IsErrRepoFileAlreadyExists(err) || files_service.IsErrCommitIDDoesNotMatch(err) || files_service.IsErrSHAOrCommitIDNotProvided(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -770,7 +770,7 @@ func GetContentsExt(ctx *context.APIContext) { case "commit_message": opts.IncludeCommitMessage = true default: - ctx.APIError(http.StatusBadRequest, fmt.Sprintf("unknown include option %q", includeOpt)) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(fmt.Sprintf("unknown include option %q", includeOpt))) return } } @@ -957,7 +957,7 @@ func handleGetFileContents(ctx *context.APIContext) { if !ok { err := json.Unmarshal(util.UnsafeStringToBytes(ctx.FormString("body")), &opts) if err != nil { - ctx.APIError(http.StatusBadRequest, "invalid body parameter") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("invalid body parameter")) return } } diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index 9d95f538743..09e78e22c54 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -105,7 +105,7 @@ func prepareDoerCreateRepoInOrg(ctx *context.APIContext, orgName string) *organi return nil } if !canCreate { - ctx.APIError(http.StatusForbidden, "User is not allowed to create repositories in this organization.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("User is not allowed to create repositories in this organization.")) return nil } } @@ -165,9 +165,9 @@ func CreateFork(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrAlreadyExist) || repo_model.IsErrReachLimitOfRepo(err) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) } else if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 5d73cc3b312..aaa5421d2e5 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -187,7 +187,7 @@ func SearchIssues(ctx *context.APIContext) { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } @@ -196,7 +196,7 @@ func SearchIssues(ctx *context.APIContext) { repoIDs, allPublic, err := buildSearchIssuesRepoIDs(ctx) if err != nil { if errors.Is(err, util.ErrNotExist) || errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -384,7 +384,7 @@ func ListIssues(ctx *context.APIContext) { // "$ref": "#/responses/notFound" before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } @@ -661,7 +661,7 @@ func CreateIssue(ctx *context.APIContext) { assigneeIDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(ctx, form.Assignee, form.Assignees) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Assignee does not exist: [name: %s]", err)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Sprintf("Assignee does not exist: [name: %s]", err))) } else { ctx.APIErrorInternal(err) } @@ -682,7 +682,7 @@ func CreateIssue(ctx *context.APIContext) { return } if !valid { - ctx.APIError(http.StatusUnprocessableEntity, repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name}) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name})) return } } @@ -693,9 +693,9 @@ func CreateIssue(ctx *context.APIContext) { if err := issue_service.NewIssue(ctx, ctx.Repo.Repository, issue, form.Labels, nil, assigneeIDs, form.Projects); err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrPermissionDenied) || errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -705,7 +705,7 @@ func CreateIssue(ctx *context.APIContext) { if form.Closed { if err := issue_service.CloseIssue(ctx, issue, ctx.Doer, ""); err != nil { if issues_model.IsErrDependenciesLeft(err) { - ctx.APIError(http.StatusPreconditionFailed, "cannot close this issue because it still has open dependencies") + ctx.APIError(http.StatusPreconditionFailed, ctx.APIErrorMessage("cannot close this issue because it still has open dependencies")) return } ctx.APIErrorInternal(err) @@ -794,7 +794,7 @@ func EditIssue(ctx *context.APIContext) { // handles concurrent requests. // TODO: wrap all mutations in a transaction to fully prevent partial writes. if form.ContentVersion != nil && *form.ContentVersion != issue.ContentVersion { - ctx.APIError(http.StatusConflict, issues_model.ErrIssueAlreadyChanged) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(issues_model.ErrIssueAlreadyChanged)) return } @@ -813,7 +813,7 @@ func EditIssue(ctx *context.APIContext) { err = issue_service.ChangeContent(ctx, issue, ctx.Doer, *form.Body, contentVersion) if err != nil { if errors.Is(err, issues_model.ErrIssueAlreadyChanged) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) return } @@ -835,7 +835,7 @@ func EditIssue(ctx *context.APIContext) { if form.RemoveDeadline == nil || !*form.RemoveDeadline { if form.Deadline == nil { - ctx.APIError(http.StatusBadRequest, "The due_date cannot be empty") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("The due_date cannot be empty")) return } if !form.Deadline.IsZero() { @@ -869,7 +869,7 @@ func EditIssue(ctx *context.APIContext) { err = issue_service.UpdateAssignees(ctx, issue, oneAssignee, form.Assignees, ctx.Doer) if err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -902,7 +902,7 @@ func EditIssue(ctx *context.APIContext) { return } if issue.PullRequest.HasMerged { - ctx.APIError(http.StatusPreconditionFailed, "cannot change state of this pull request, it was already merged") + ctx.APIError(http.StatusPreconditionFailed, ctx.APIErrorMessage("cannot change state of this pull request, it was already merged")) return } } @@ -918,7 +918,7 @@ func EditIssue(ctx *context.APIContext) { if canWrite && form.Projects != nil { if err := issues_model.IssueAssignOrRemoveProject(ctx, issue, ctx.Doer, *form.Projects); err != nil { if errors.Is(err, util.ErrPermissionDenied) || errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -1034,7 +1034,7 @@ func UpdateIssueDeadline(ctx *context.APIContext) { } if !ctx.Repo.Permission.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.APIError(http.StatusForbidden, "Not repo writer") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Not repo writer")) return } @@ -1049,14 +1049,14 @@ func UpdateIssueDeadline(ctx *context.APIContext) { func closeOrReopenIssue(ctx *context.APIContext, issue *issues_model.Issue, state api.StateType) { if state != api.StateOpen && state != api.StateClosed { - ctx.APIError(http.StatusPreconditionFailed, fmt.Sprintf("unknown state: %s", state)) + ctx.APIError(http.StatusPreconditionFailed, ctx.APIErrorMessage(fmt.Sprintf("unknown state: %s", state))) return } if state == api.StateClosed && !issue.IsClosed { if err := issue_service.CloseIssue(ctx, issue, ctx.Doer, ""); err != nil { if issues_model.IsErrDependenciesLeft(err) { - ctx.APIError(http.StatusPreconditionFailed, "cannot close this issue or pull request because it still has open dependencies") + ctx.APIError(http.StatusPreconditionFailed, ctx.APIErrorMessage("cannot close this issue or pull request because it still has open dependencies")) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/issue_attachment.go b/routers/api/v1/repo/issue_attachment.go index 00fa792771f..7be79c9547b 100644 --- a/routers/api/v1/repo/issue_attachment.go +++ b/routers/api/v1/repo/issue_attachment.go @@ -194,9 +194,9 @@ func CreateIssueAttachment(ctx *context.APIContext) { }) if err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrContentTooLarge) { - ctx.APIError(http.StatusRequestEntityTooLarge, err) + ctx.APIError(http.StatusRequestEntityTooLarge, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -272,7 +272,7 @@ func EditIssueAttachment(ctx *context.APIContext) { if err := attachment_service.UpdateAttachment(ctx, setting.Attachment.AllowedTypes, attachment); err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -373,7 +373,7 @@ func getIssueAttachmentSafeRead(ctx *context.APIContext, issue *issues_model.Iss func canUserWriteIssueAttachment(ctx *context.APIContext, issue *issues_model.Issue) bool { canEditIssue := ctx.IsSigned && (ctx.Doer.ID == issue.PosterID || ctx.IsUserRepoAdmin() || ctx.IsUserSiteAdmin() || ctx.Repo.Permission.CanWriteIssuesOrPulls(issue.IsPull)) if !canEditIssue { - ctx.APIError(http.StatusForbidden, "user should have permission to write issue") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should have permission to write issue")) return false } diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 5b2d2084735..c43e2a52038 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -65,7 +65,7 @@ func ListIssueComments(ctx *context.APIContext) { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) @@ -169,7 +169,7 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) @@ -274,7 +274,7 @@ func ListRepoIssueComments(ctx *context.APIContext) { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } @@ -392,14 +392,14 @@ func CreateIssueComment(ctx *context.APIContext) { } if issue.IsLocked && !ctx.Repo.Permission.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin { - ctx.APIError(http.StatusForbidden, errors.New(ctx.Locale.TrString("repo.issues.comment_on_locked"))) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New(ctx.Locale.TrString("repo.issues.comment_on_locked")))) return } comment, err := issue_service.CreateIssueComment(ctx, ctx.Doer, ctx.Repo.Repository, issue, form.Body, nil) if err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -595,7 +595,7 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) comment.Content = form.Body if err := issue_service.UpdateComment(ctx, comment, comment.ContentVersion, ctx.Doer, oldContent); err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/issue_comment_attachment.go b/routers/api/v1/repo/issue_comment_attachment.go index d2650edb634..c3384f45716 100644 --- a/routers/api/v1/repo/issue_comment_attachment.go +++ b/routers/api/v1/repo/issue_comment_attachment.go @@ -202,9 +202,9 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) { }) if err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrContentTooLarge) { - ctx.APIError(http.StatusRequestEntityTooLarge, err) + ctx.APIError(http.StatusRequestEntityTooLarge, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -218,7 +218,7 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) { if err = issue_service.UpdateComment(ctx, comment, comment.ContentVersion, ctx.Doer, comment.Content); err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -285,7 +285,7 @@ func EditIssueCommentAttachment(ctx *context.APIContext) { if err := attachment_service.UpdateAttachment(ctx, setting.Attachment.AllowedTypes, attach); err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -354,7 +354,7 @@ func getIssueCommentSafe(ctx *context.APIContext) *issues_model.Comment { return nil } if comment.Issue == nil || comment.Issue.RepoID != ctx.Repo.Repository.ID { - ctx.APIError(http.StatusNotFound, "no matching issue comment found") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("no matching issue comment found")) return nil } @@ -381,7 +381,7 @@ func getIssueCommentAttachmentSafeWrite(ctx *context.APIContext) *repo_model.Att func canUserWriteIssueCommentAttachment(ctx *context.APIContext, comment *issues_model.Comment) bool { canEditComment := ctx.IsSigned && (ctx.Doer.ID == comment.PosterID || ctx.IsUserRepoAdmin() || ctx.IsUserSiteAdmin()) && ctx.Repo.Permission.CanWriteIssuesOrPulls(comment.Issue.IsPull) if !canEditComment { - ctx.APIError(http.StatusForbidden, "user should have permission to edit comment") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should have permission to edit comment")) return false } diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index ecf42688615..36781917b31 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -181,7 +181,7 @@ func DeleteIssueLabel(ctx *context.APIContext) { label, err := issues_model.GetLabelByID(ctx, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrLabelNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -320,7 +320,7 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) } if !ctx.Repo.Permission.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.APIError(http.StatusForbidden, "write permission is required") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("write permission is required")) return nil, nil, errors.New("permission denied") } @@ -336,12 +336,12 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) case reflect.String: labelNames = append(labelNames, rv.String()) default: - ctx.APIError(http.StatusBadRequest, "a label must be an integer or a string") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("a label must be an integer or a string")) return nil, nil, errors.New("invalid label") } } if len(labelIDs) > 0 && len(labelNames) > 0 { - ctx.APIError(http.StatusBadRequest, "labels should be an array of strings or integers") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("labels should be an array of strings or integers")) return nil, nil, errors.New("invalid labels") } if len(labelNames) > 0 { diff --git a/routers/api/v1/repo/issue_lock.go b/routers/api/v1/repo/issue_lock.go index 283b441fd20..18fc4372859 100644 --- a/routers/api/v1/repo/issue_lock.go +++ b/routers/api/v1/repo/issue_lock.go @@ -63,7 +63,7 @@ func LockIssue(ctx *context.APIContext) { } if !ctx.Repo.Permission.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.APIError(http.StatusForbidden, errors.New("no permission to lock this issue")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("no permission to lock this issue"))) return } @@ -130,7 +130,7 @@ func UnlockIssue(ctx *context.APIContext) { } if !ctx.Repo.Permission.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.APIError(http.StatusForbidden, errors.New("no permission to unlock this issue")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("no permission to unlock this issue"))) return } diff --git a/routers/api/v1/repo/issue_pin.go b/routers/api/v1/repo/issue_pin.go index b8cebfbb04e..06ddca2f761 100644 --- a/routers/api/v1/repo/issue_pin.go +++ b/routers/api/v1/repo/issue_pin.go @@ -46,7 +46,7 @@ func PinIssue(ctx *context.APIContext) { if issues_model.IsErrIssueNotExist(err) { ctx.APIErrorNotFound() } else if issues_model.IsErrIssueMaxPinReached(err) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go index 3662e63c71b..90abd630e10 100644 --- a/routers/api/v1/repo/issue_reaction.go +++ b/routers/api/v1/repo/issue_reaction.go @@ -72,7 +72,7 @@ func GetIssueCommentReactions(ctx *context.APIContext) { } if !ctx.Repo.Permission.CanReadIssuesOrPulls(comment.Issue.IsPull) { - ctx.APIError(http.StatusForbidden, errors.New("no permission to get reactions")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("no permission to get reactions"))) return } @@ -214,7 +214,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp } if comment.Issue.IsLocked && !ctx.Repo.Permission.CanWriteIssuesOrPulls(comment.Issue.IsPull) { - ctx.APIError(http.StatusForbidden, errors.New("no permission to change reaction")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("no permission to change reaction"))) return } @@ -223,7 +223,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp reaction, err := issue_service.CreateCommentReaction(ctx, ctx.Doer, comment, form.Reaction) if err != nil { if issues_model.IsErrForbiddenIssueReaction(err) || errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else if issues_model.IsErrReactionAlreadyExist(err) { ctx.JSON(http.StatusOK, api.Reaction{ User: convert.ToUser(ctx, ctx.Doer, ctx.Doer), @@ -305,7 +305,7 @@ func GetIssueReactions(ctx *context.APIContext) { } if !ctx.Repo.Permission.CanReadIssuesOrPulls(issue.IsPull) { - ctx.APIError(http.StatusForbidden, errors.New("no permission to get reactions")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("no permission to get reactions"))) return } @@ -429,7 +429,7 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i } if issue.IsLocked && !ctx.Repo.Permission.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.APIError(http.StatusForbidden, errors.New("no permission to change reaction")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("no permission to change reaction"))) return } @@ -438,7 +438,7 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i reaction, err := issue_service.CreateIssueReaction(ctx, ctx.Doer, issue, form.Reaction) if err != nil { if issues_model.IsErrForbiddenIssueReaction(err) || errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else if issues_model.IsErrReactionAlreadyExist(err) { ctx.JSON(http.StatusOK, api.Reaction{ User: convert.ToUser(ctx, ctx.Doer, ctx.Doer), diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go index 36f24ed27ce..3b422d82a4e 100644 --- a/routers/api/v1/repo/issue_stopwatch.go +++ b/routers/api/v1/repo/issue_stopwatch.go @@ -57,7 +57,7 @@ func StartIssueStopwatch(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if !ok { - ctx.APIError(http.StatusConflict, "cannot start a stopwatch again if it already exists") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("cannot start a stopwatch again if it already exists")) return } @@ -109,7 +109,7 @@ func StopIssueStopwatch(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if !ok { - ctx.APIError(http.StatusConflict, "cannot stop a non-existent stopwatch") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("cannot stop a non-existent stopwatch")) return } ctx.Status(http.StatusCreated) @@ -160,7 +160,7 @@ func DeleteIssueStopwatch(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if !ok { - ctx.APIError(http.StatusConflict, "cannot cancel a non-existent stopwatch") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("cannot cancel a non-existent stopwatch")) return } diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index b2480e88a5a..5dac59cd099 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -128,7 +128,7 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { // only admin and user for itself can change subscription if user.ID != ctx.Doer.ID && !ctx.Doer.IsAdmin { - ctx.APIError(http.StatusForbidden, fmt.Errorf("%s is not permitted to change subscriptions for %s", ctx.Doer.Name, user.Name)) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(fmt.Errorf("%s is not permitted to change subscriptions for %s", ctx.Doer.Name, user.Name))) return } diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go index 414b44f5246..425b937a308 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -95,7 +95,7 @@ func ListTrackedTimes(ctx *context.APIContext) { if qUser != "" { user, err := user_model.GetUserByName(ctx, qUser) if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else if err != nil { ctx.APIErrorInternal(err) return @@ -104,7 +104,7 @@ func ListTrackedTimes(ctx *context.APIContext) { } if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = context.GetQueryBeforeSince(ctx.Base); err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } @@ -116,7 +116,7 @@ func ListTrackedTimes(ctx *context.APIContext) { if opts.UserID == 0 { opts.UserID = ctx.Doer.ID } else { - ctx.APIError(http.StatusForbidden, errors.New("query by user not allowed; not enough rights")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("query by user not allowed; not enough rights"))) return } } @@ -193,7 +193,7 @@ func AddTime(ctx *context.APIContext) { if !ctx.Repo.CanUseTimetracker(ctx, issue, ctx.Doer) { if !ctx.Repo.Repository.IsTimetrackerEnabled(ctx) { - ctx.APIError(http.StatusBadRequest, "time tracking disabled") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("time tracking disabled")) return } ctx.Status(http.StatusForbidden) @@ -286,7 +286,7 @@ func ResetIssueTime(ctx *context.APIContext) { err = issues_model.DeleteIssueUserTimes(ctx, issue, ctx.Doer) if err != nil { if db.IsErrNotExist(err) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -419,7 +419,7 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !ctx.Repo.Repository.IsTimetrackerEnabled(ctx) { - ctx.APIError(http.StatusBadRequest, "time tracking disabled") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("time tracking disabled")) return } user, err := user_model.GetUserByName(ctx, ctx.PathParam("timetrackingusername")) @@ -437,7 +437,7 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { } if !ctx.IsUserRepoAdmin() && !ctx.Doer.IsAdmin && ctx.Doer.ID != user.ID { - ctx.APIError(http.StatusForbidden, errors.New("query by user not allowed; not enough rights")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("query by user not allowed; not enough rights"))) return } @@ -509,7 +509,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !ctx.Repo.Repository.IsTimetrackerEnabled(ctx) { - ctx.APIError(http.StatusBadRequest, "time tracking disabled") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("time tracking disabled")) return } @@ -523,7 +523,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { if qUser != "" { user, err := user_model.GetUserByName(ctx, qUser) if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else if err != nil { ctx.APIErrorInternal(err) return @@ -533,7 +533,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { var err error if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = context.GetQueryBeforeSince(ctx.Base); err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } @@ -545,7 +545,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { if opts.UserID == 0 { opts.UserID = ctx.Doer.ID } else { - ctx.APIError(http.StatusForbidden, errors.New("query by user not allowed; not enough rights")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("query by user not allowed; not enough rights"))) return } } @@ -607,7 +607,7 @@ func ListMyTrackedTimes(ctx *context.APIContext) { var err error if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = context.GetQueryBeforeSince(ctx.Base); err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go index 44471a4f73f..98a48fa29ca 100644 --- a/routers/api/v1/repo/key.go +++ b/routers/api/v1/repo/key.go @@ -175,11 +175,11 @@ func GetDeployKey(ctx *context.APIContext) { // HandleCheckKeyStringError handle check key error func HandleCheckKeyStringError(ctx *context.APIContext, err error) { if db.IsErrSSHDisabled(err) { - ctx.APIError(http.StatusUnprocessableEntity, "SSH is disabled") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("SSH is disabled")) } else if asymkey_model.IsErrKeyUnableVerify(err) { - ctx.APIError(http.StatusUnprocessableEntity, "Unable to verify key content") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Unable to verify key content")) } else { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid key content: %w", err)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("Invalid key content: %w", err))) } } @@ -187,13 +187,13 @@ func HandleCheckKeyStringError(ctx *context.APIContext, err error) { func HandleAddKeyError(ctx *context.APIContext, err error) { switch { case asymkey_model.IsErrDeployKeyAlreadyExist(err): - ctx.APIError(http.StatusUnprocessableEntity, "This key has already been added to this repository") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("This key has already been added to this repository")) case asymkey_model.IsErrKeyAlreadyExist(err): - ctx.APIError(http.StatusUnprocessableEntity, "Key content has been used as non-deploy key") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Key content has been used as non-deploy key")) case asymkey_model.IsErrKeyNameAlreadyUsed(err): - ctx.APIError(http.StatusUnprocessableEntity, "Key title has been used") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Key title has been used")) case asymkey_model.IsErrDeployKeyNameAlreadyUsed(err): - ctx.APIError(http.StatusUnprocessableEntity, "A key with the same name already exists") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("A key with the same name already exists")) default: ctx.APIErrorInternal(err) } @@ -281,7 +281,7 @@ func DeleteDeploykey(ctx *context.APIContext) { if err := asymkey_service.DeleteDeployKey(ctx, ctx.Repo.Repository, ctx.PathParamInt64("id")); err != nil { if asymkey_model.IsErrKeyAccessDenied(err) { - ctx.APIError(http.StatusForbidden, "You do not have access to this key") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("You do not have access to this key")) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go index aec82dce757..8a473aa1dbb 100644 --- a/routers/api/v1/repo/label.go +++ b/routers/api/v1/repo/label.go @@ -153,7 +153,7 @@ func CreateLabel(ctx *context.APIContext) { color, err := label.NormalizeColor(form.Color) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } form.Color = color @@ -231,7 +231,7 @@ func EditLabel(ctx *context.APIContext) { if form.Color != nil { color, err := label.NormalizeColor(*form.Color) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } l.Color = color diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go index 65ef10777c4..8e1b6d8bae8 100644 --- a/routers/api/v1/repo/migrate.go +++ b/routers/api/v1/repo/migrate.go @@ -72,7 +72,7 @@ func Migrate(ctx *context.APIContext) { } if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -81,7 +81,7 @@ func Migrate(ctx *context.APIContext) { if !ctx.Doer.IsAdmin { if !repoOwner.IsOrganization() && ctx.Doer.ID != repoOwner.ID { - ctx.APIError(http.StatusForbidden, "Given user is not an organization.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Given user is not an organization.")) return } @@ -92,7 +92,7 @@ func Migrate(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if !isOwner { - ctx.APIError(http.StatusForbidden, "Given user is not owner of organization.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Given user is not owner of organization.")) return } } @@ -110,12 +110,12 @@ func Migrate(ctx *context.APIContext) { gitServiceType := convert.ToGitServiceType(form.Service) if form.Mirror && setting.Mirror.DisableNewPull { - ctx.APIError(http.StatusForbidden, errors.New("the site administrator has disabled the creation of new pull mirrors")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("the site administrator has disabled the creation of new pull mirrors"))) return } if setting.Repository.DisableMigrations { - ctx.APIError(http.StatusForbidden, errors.New("the site administrator has disabled migrations")) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(errors.New("the site administrator has disabled migrations"))) return } @@ -219,33 +219,33 @@ func Migrate(ctx *context.APIContext) { func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, err error) { switch { case repo_model.IsErrRepoAlreadyExist(err): - ctx.APIError(http.StatusConflict, "The repository with the same name already exists.") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("The repository with the same name already exists.")) case repo_model.IsErrRepoFilesAlreadyExist(err): - ctx.APIError(http.StatusConflict, "Files already exist for this repository. Adopt them or delete them.") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("Files already exist for this repository. Adopt them or delete them.")) case migrations.IsRateLimitError(err): - ctx.APIError(http.StatusUnprocessableEntity, "Remote visit addressed rate limitation.") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Remote visit addressed rate limitation.")) case migrations.IsTwoFactorAuthError(err): - ctx.APIError(http.StatusUnprocessableEntity, "Remote visit required two factors authentication.") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Remote visit required two factors authentication.")) case repo_model.IsErrReachLimitOfRepo(err): - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("You have already reached your limit of %d repositories.", repoOwner.MaxCreationLimit())) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Sprintf("You have already reached your limit of %d repositories.", repoOwner.MaxCreationLimit()))) case db.IsErrNameReserved(err): - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("The username '%s' is reserved.", err.(db.ErrNameReserved).Name)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Sprintf("The username '%s' is reserved.", err.(db.ErrNameReserved).Name))) case db.IsErrNameCharsNotAllowed(err): - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("The username '%s' contains invalid characters.", err.(db.ErrNameCharsNotAllowed).Name)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Sprintf("The username '%s' contains invalid characters.", err.(db.ErrNameCharsNotAllowed).Name))) case db.IsErrNamePatternNotAllowed(err): - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("The pattern '%s' is not allowed in a username.", err.(db.ErrNamePatternNotAllowed).Pattern)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Sprintf("The pattern '%s' is not allowed in a username.", err.(db.ErrNamePatternNotAllowed).Pattern))) case git.IsErrInvalidCloneAddr(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) case base.IsErrNotSupported(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) default: err = util.SanitizeErrorCredentialURLs(err) if strings.Contains(err.Error(), "Authentication failed") || strings.Contains(err.Error(), "Bad credentials") || strings.Contains(err.Error(), "could not read Username") { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Authentication failed: %v.", err)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Sprintf("Authentication failed: %v.", err))) } else if strings.Contains(err.Error(), "fatal:") { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Migration failed: %v.", err)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Sprintf("Migration failed: %v.", err))) } else { ctx.APIErrorInternal(err) } @@ -257,15 +257,15 @@ func handleRemoteAddrError(ctx *context.APIContext, err error) { addrErr := err.(*git.ErrInvalidCloneAddr) switch { case addrErr.IsURLError: - ctx.APIError(http.StatusUnprocessableEntity, "The provided URL is invalid.") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("The provided URL is invalid.")) case addrErr.IsPermissionDenied: if addrErr.LocalPath { - ctx.APIError(http.StatusUnprocessableEntity, "You are not allowed to import local repositories.") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("You are not allowed to import local repositories.")) } else { - ctx.APIError(http.StatusUnprocessableEntity, "You can not import from disallowed hosts.") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("You can not import from disallowed hosts.")) } case addrErr.IsInvalidPath: - ctx.APIError(http.StatusUnprocessableEntity, "Invalid local path, it does not exist or not a directory.") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Invalid local path, it does not exist or not a directory.")) default: ctx.APIErrorInternal(fmt.Errorf("unknown error type (ErrInvalidCloneAddr): %w", err)) } diff --git a/routers/api/v1/repo/mirror.go b/routers/api/v1/repo/mirror.go index 53d47ff135e..593073f2120 100644 --- a/routers/api/v1/repo/mirror.go +++ b/routers/api/v1/repo/mirror.go @@ -53,17 +53,17 @@ func MirrorSync(ctx *context.APIContext) { repo := ctx.Repo.Repository if !ctx.Repo.Permission.CanWrite(unit.TypeCode) { - ctx.APIError(http.StatusForbidden, "Must have write access") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Must have write access")) } if !setting.Mirror.Enabled { - ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Mirror feature is disabled")) return } if _, err := repo_model.GetMirrorByRepoID(ctx, repo.ID); err != nil { if errors.Is(err, repo_model.ErrMirrorNotExist) { - ctx.APIError(http.StatusBadRequest, "Repository is not a mirror") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Repository is not a mirror")) return } ctx.APIErrorInternal(err) @@ -106,13 +106,13 @@ func PushMirrorSync(ctx *context.APIContext) { // "$ref": "#/responses/validationError" if !setting.Mirror.Enabled { - ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Mirror feature is disabled")) return } // Get All push mirrors of a specific repo pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, ctx.Repo.Repository.ID, db.ListOptions{}) if err != nil { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) return } @@ -124,7 +124,7 @@ func PushMirrorSync(ctx *context.APIContext) { } } if len(failedPushMirrors) != 0 { - ctx.APIError(http.StatusUnprocessableEntity, "error occurred when syncing push mirrors: "+strings.Join(failedPushMirrors, ", ")) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("error occurred when syncing push mirrors: "+strings.Join(failedPushMirrors, ", "))) return } ctx.Status(http.StatusOK) @@ -167,7 +167,7 @@ func ListPushMirrors(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !setting.Mirror.Enabled { - ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Mirror feature is disabled")) return } @@ -175,7 +175,7 @@ func ListPushMirrors(ctx *context.APIContext) { // Get all push mirrors for the specified repository. pushMirrors, count, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, utils.GetListOptions(ctx)) if err != nil { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) return } @@ -225,7 +225,7 @@ func GetPushMirrorByName(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !setting.Mirror.Enabled { - ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Mirror feature is disabled")) return } @@ -239,7 +239,7 @@ func GetPushMirrorByName(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if !exist { - ctx.APIError(http.StatusNotFound, nil) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(nil)) return } @@ -286,7 +286,7 @@ func AddPushMirror(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !setting.Mirror.Enabled { - ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Mirror feature is disabled")) return } @@ -326,7 +326,7 @@ func DeletePushMirrorByRemoteName(ctx *context.APIContext) { // "$ref": "#/responses/error" if !setting.Mirror.Enabled { - ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Mirror feature is disabled")) return } @@ -334,7 +334,7 @@ func DeletePushMirrorByRemoteName(ctx *context.APIContext) { // Delete push mirror on repo by name. err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{RepoID: ctx.Repo.Repository.ID, RemoteName: remoteName}) if err != nil { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) return } ctx.Status(http.StatusNoContent) @@ -345,7 +345,7 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro interval, err := time.ParseDuration(mirrorOption.Interval) if err != nil || (interval != 0 && interval < setting.Mirror.MinInterval) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } @@ -402,13 +402,13 @@ func HandleRemoteAddressError(ctx *context.APIContext, err error) { addrErr := err.(*git.ErrInvalidCloneAddr) switch { case addrErr.IsProtocolInvalid: - ctx.APIError(http.StatusBadRequest, "Invalid mirror protocol") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Invalid mirror protocol")) case addrErr.IsURLError: - ctx.APIError(http.StatusBadRequest, "Invalid Url ") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Invalid Url ")) case addrErr.IsPermissionDenied: - ctx.APIError(http.StatusUnauthorized, "Permission denied") + ctx.APIError(http.StatusUnauthorized, ctx.APIErrorMessage("Permission denied")) default: - ctx.APIError(http.StatusBadRequest, "Unknown error") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Unknown error")) } return } diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go index d8fea56c4cd..8d5e6d4d9b4 100644 --- a/routers/api/v1/repo/notes.go +++ b/routers/api/v1/repo/notes.go @@ -54,7 +54,7 @@ func GetNote(ctx *context.APIContext) { sha := ctx.PathParam("sha") if !git.IsValidRefPattern(sha) { - ctx.APIError(http.StatusUnprocessableEntity, "no valid ref or sha: "+sha) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("no valid ref or sha: "+sha)) return } getNote(ctx, sha) diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 6f6ba77fae0..8d0806ad57d 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -126,7 +126,7 @@ func ListPullRequests(ctx *context.APIContext) { poster, err := user_model.GetUserByName(ctx, posterStr) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -407,7 +407,7 @@ func CreatePullRequest(ctx *context.APIContext) { form := *web.GetForm(ctx).(*api.CreatePullRequestOption) if form.Head == form.Base { - ctx.APIError(http.StatusUnprocessableEntity, "Invalid PullRequest: There are no changes between the head and the base") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Invalid PullRequest: There are no changes between the head and the base")) return } @@ -425,7 +425,7 @@ func CreatePullRequest(ctx *context.APIContext) { defer closer() if !compareResult.BaseRef.IsBranch() || !compareResult.HeadRef.IsBranch() { - ctx.APIError(http.StatusUnprocessableEntity, "Invalid PullRequest: base and head must be branches") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Invalid PullRequest: base and head must be branches")) return } @@ -448,7 +448,7 @@ func CreatePullRequest(ctx *context.APIContext) { HeadBranch: existingPr.HeadBranch, BaseBranch: existingPr.BaseBranch, } - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) return } @@ -531,7 +531,7 @@ func CreatePullRequest(ctx *context.APIContext) { assigneeIDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(ctx, form.Assignee, form.Assignees) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Assignee does not exist: [name: %s]", err)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Sprintf("Assignee does not exist: [name: %s]", err))) } else { ctx.APIErrorInternal(err) } @@ -551,7 +551,7 @@ func CreatePullRequest(ctx *context.APIContext) { return } if !valid { - ctx.APIError(http.StatusUnprocessableEntity, repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name})) return } } @@ -570,11 +570,11 @@ func CreatePullRequest(ctx *context.APIContext) { if err := pull_service.NewPullRequest(ctx, prOpts); err != nil { if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else if errors.Is(err, issues_model.ErrMustCollaborator) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -663,7 +663,7 @@ func EditPullRequest(ctx *context.APIContext) { // handles concurrent requests. // TODO: wrap all mutations in a transaction to fully prevent partial writes. if form.ContentVersion != nil && *form.ContentVersion != issue.ContentVersion { - ctx.APIError(http.StatusConflict, issues_model.ErrIssueAlreadyChanged) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(issues_model.ErrIssueAlreadyChanged)) return } @@ -682,7 +682,7 @@ func EditPullRequest(ctx *context.APIContext) { err = issue_service.ChangeContent(ctx, issue, ctx.Doer, *form.Body, contentVersion) if err != nil { if errors.Is(err, issues_model.ErrIssueAlreadyChanged) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) return } @@ -719,9 +719,9 @@ func EditPullRequest(ctx *context.APIContext) { err = issue_service.UpdateAssignees(ctx, issue, form.Assignee, form.Assignees, ctx.Doer) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Assignee does not exist: [name: %s]", err)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Sprintf("Assignee does not exist: [name: %s]", err))) } else if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -769,7 +769,7 @@ func EditPullRequest(ctx *context.APIContext) { if form.State != nil { if pr.HasMerged { - ctx.APIError(http.StatusPreconditionFailed, "cannot change state of this pull request, it was already merged") + ctx.APIError(http.StatusPreconditionFailed, ctx.APIErrorMessage("cannot change state of this pull request, it was already merged")) return } @@ -788,18 +788,18 @@ func EditPullRequest(ctx *context.APIContext) { return } if !branchExist { - ctx.APIError(http.StatusNotFound, fmt.Errorf("new base '%s' not exist", form.Base)) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(fmt.Errorf("new base '%s' not exist", form.Base))) return } if err := pull_service.ChangeTargetBranch(ctx, pr, ctx.Doer, form.Base); err != nil { if issues_model.IsErrPullRequestAlreadyExists(err) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) return } else if issues_model.IsErrIssueIsClosed(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } else if pull_service.IsErrPullRequestHasMerged(err) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -812,7 +812,7 @@ func EditPullRequest(ctx *context.APIContext) { if form.AllowMaintainerEdit != nil { if err := pull_service.SetAllowEdits(ctx, ctx.Doer, pr, *form.AllowMaintainerEdit); err != nil { if errors.Is(err, pull_service.ErrUserHasNoPermissionForAction) { - ctx.APIError(http.StatusForbidden, fmt.Sprintf("SetAllowEdits: %s", err)) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(fmt.Sprintf("SetAllowEdits: %s", err))) return } ctx.APIErrorInternal(err) @@ -969,19 +969,19 @@ func MergePullRequest(ctx *context.APIContext) { if errors.Is(err, pull_service.ErrIsClosed) { ctx.APIErrorNotFound() } else if errors.Is(err, pull_service.ErrNoPermissionToMerge) { - ctx.APIError(http.StatusMethodNotAllowed, "User not allowed to merge PR") + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage("User not allowed to merge PR")) } else if errors.Is(err, pull_service.ErrHasMerged) { - ctx.APIError(http.StatusMethodNotAllowed, "The PR is already merged") + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage("The PR is already merged")) } else if errors.Is(err, pull_service.ErrIsWorkInProgress) { - ctx.APIError(http.StatusMethodNotAllowed, "Work in progress PRs cannot be merged") + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage("Work in progress PRs cannot be merged")) } else if errors.Is(err, pull_service.ErrNotMergeableState) { - ctx.APIError(http.StatusMethodNotAllowed, "Please try again later") + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage("Please try again later")) } else if errors.Is(err, pull_service.ErrNotReadyToMerge) { - ctx.APIError(http.StatusMethodNotAllowed, err) + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage(err)) } else if asymkey_service.IsErrWontSign(err) { - ctx.APIError(http.StatusMethodNotAllowed, err) + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage(err)) } else if errors.Is(err, pull_service.ErrHeadCommitsNotAllVerified) { - ctx.APIError(http.StatusMethodNotAllowed, err) + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -992,11 +992,11 @@ func MergePullRequest(ctx *context.APIContext) { if manuallyMerged { if err := pull_service.MergedManually(ctx, pr, ctx.Doer, ctx.Repo.GitRepo, form.MergeCommitID); err != nil { if pull_service.IsErrInvalidMergeStyle(err) { - ctx.APIError(http.StatusMethodNotAllowed, fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do))) + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage(fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do)))) return } if strings.Contains(err.Error(), "Wrong commit ID") { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1034,7 +1034,7 @@ func MergePullRequest(ctx *context.APIContext) { scheduled, err := automerge.ScheduleAutoMerge(ctx, ctx.Doer, pr, repo_model.MergeStyle(form.Do), message, deleteBranchAfterMerge) if err != nil { if pull_model.IsErrAlreadyScheduledToAutoMerge(err) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1048,7 +1048,7 @@ func MergePullRequest(ctx *context.APIContext) { if err := pull_service.Merge(ctx, pr, ctx.Doer, repo_model.MergeStyle(form.Do), form.HeadCommitID, message, false); err != nil { if pull_service.IsErrInvalidMergeStyle(err) { - ctx.APIError(http.StatusMethodNotAllowed, fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do))) + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage(fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do)))) } else if pull_service.IsErrMergeConflicts(err) { conflictError := err.(pull_service.ErrMergeConflicts) ctx.JSON(http.StatusConflict, conflictError) @@ -1059,15 +1059,15 @@ func MergePullRequest(ctx *context.APIContext) { conflictError := err.(pull_service.ErrMergeUnrelatedHistories) ctx.JSON(http.StatusConflict, conflictError) } else if git.IsErrPushOutOfDate(err) { - ctx.APIError(http.StatusConflict, "merge push out of date") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("merge push out of date")) } else if pull_service.IsErrSHADoesNotMatch(err) { - ctx.APIError(http.StatusConflict, "head out of date") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("head out of date")) } else if git.IsErrPushRejected(err) { errPushRej := err.(*git.ErrPushRejected) if len(errPushRej.Message) == 0 { - ctx.APIError(http.StatusConflict, "PushRejected without remote error message") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("PushRejected without remote error message")) } else { - ctx.APIError(http.StatusConflict, "PushRejected with remote message: "+errPushRej.Message) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("PushRejected with remote message: "+errPushRej.Message)) } } else { ctx.APIErrorInternal(err) @@ -1093,14 +1093,14 @@ func parseCompareInfo(ctx *context.APIContext, compareParam string) (result *git // remove the check when we support compare with carets if compareReq.BaseOriRefSuffix != "" { - ctx.APIError(http.StatusBadRequest, "Unsupported comparison syntax: ref with suffix") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Unsupported comparison syntax: ref with suffix")) return nil, nil } _, headRepo, err := common.GetHeadOwnerAndRepo(ctx, baseRepo, compareReq) switch { case errors.Is(err, util.ErrInvalidArgument): - ctx.APIError(http.StatusBadRequest, err.Error()) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err.Error())) return nil, nil case errors.Is(err, util.ErrNotExist): ctx.APIErrorNotFound() @@ -1230,7 +1230,7 @@ func UpdatePullRequest(ctx *context.APIContext) { } if pr.HasMerged { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } @@ -1240,7 +1240,7 @@ func UpdatePullRequest(ctx *context.APIContext) { } if pr.Issue.IsClosed { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } @@ -1273,10 +1273,10 @@ func UpdatePullRequest(ctx *context.APIContext) { if err = pull_service.Update(graceful.GetManager().ShutdownContext(), pr, ctx.Doer, message, rebase); err != nil { if pull_service.IsErrMergeConflicts(err) { - ctx.APIError(http.StatusConflict, "merge failed because of conflict") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("merge failed because of conflict")) return } else if pull_service.IsErrRebaseConflicts(err) { - ctx.APIError(http.StatusConflict, "rebase failed because of conflict") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("rebase failed because of conflict")) return } ctx.APIErrorInternal(err) @@ -1348,7 +1348,7 @@ func CancelScheduledAutoMerge(ctx *context.APIContext) { return } if !allowed { - ctx.APIError(http.StatusForbidden, "user has no permission to cancel the scheduled auto merge") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user has no permission to cancel the scheduled auto merge")) return } } @@ -1436,7 +1436,7 @@ func GetPullRequestCommits(ctx *context.APIContext) { } if gitcmd.IsStderr(err, gitcmd.StderrBadRevision) { - ctx.APIError(http.StatusNotFound, "invalid base branch or revision") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("invalid base branch or revision")) return } else if err != nil { ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index 901e6b69c08..3b6fe375f86 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -267,7 +267,7 @@ func CreatePullReviewCommentReply(ctx *context.APIContext) { return } if parent.ReviewID == 0 { - ctx.APIError(http.StatusBadRequest, "comment is not a review comment") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("comment is not a review comment")) return } @@ -374,7 +374,7 @@ func updatePullReviewCommentResolve(ctx *context.APIContext, isResolve bool) { return } if !canMarkConv { - ctx.APIError(http.StatusForbidden, "user should have permission to resolve comment") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user should have permission to resolve comment")) return } @@ -398,12 +398,12 @@ func getPullReviewCommentToResolve(ctx *context.APIContext) *issues_model.Commen } if !comment.Issue.IsPull { - ctx.APIError(http.StatusBadRequest, "comment does not belong to a pull request") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("comment does not belong to a pull request")) return nil } if comment.Type != issues_model.CommentTypeCode { - ctx.APIError(http.StatusBadRequest, "comment is not a review comment") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("comment is not a review comment")) return nil } @@ -458,7 +458,7 @@ func DeletePullReview(ctx *context.APIContext) { return } if !ctx.Doer.IsAdmin && ctx.Doer.ID != review.ReviewerID { - ctx.APIError(http.StatusForbidden, nil) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(nil)) return } @@ -575,7 +575,7 @@ func CreatePullReview(ctx *context.APIContext) { review, _, err := pull_service.SubmitReview(ctx, ctx.Doer, ctx.Repo.GitRepo, pr.Issue, reviewType, opts.Body, opts.CommitID, nil) if err != nil { if errors.Is(err, pull_service.ErrSubmitReviewOnClosedPR) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -641,7 +641,7 @@ func SubmitPullReview(ctx *context.APIContext) { } if review.Type != issues_model.ReviewTypePending { - ctx.APIError(http.StatusUnprocessableEntity, errors.New("only a pending review can be submitted")) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(errors.New("only a pending review can be submitted"))) return } @@ -653,7 +653,7 @@ func SubmitPullReview(ctx *context.APIContext) { // if review stay pending return if reviewType == issues_model.ReviewTypePending { - ctx.APIError(http.StatusUnprocessableEntity, errors.New("review stay pending")) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(errors.New("review stay pending"))) return } @@ -667,7 +667,7 @@ func SubmitPullReview(ctx *context.APIContext) { review, _, err = pull_service.SubmitReview(ctx, ctx.Doer, ctx.Repo.GitRepo, pr.Issue, reviewType, opts.Body, headCommitID, nil) if err != nil { if errors.Is(err, pull_service.ErrSubmitReviewOnClosedPR) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -698,7 +698,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest case api.ReviewStateApproved: // can not approve your own PR if pr.Issue.IsPoster(ctx.Doer.ID) { - ctx.APIError(http.StatusUnprocessableEntity, errors.New("approve your own pull is not allowed")) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(errors.New("approve your own pull is not allowed"))) return -1, true } reviewType = issues_model.ReviewTypeApprove @@ -707,7 +707,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest case api.ReviewStateRequestChanges: // can not reject your own PR if pr.Issue.IsPoster(ctx.Doer.ID) { - ctx.APIError(http.StatusUnprocessableEntity, errors.New("reject your own pull is not allowed")) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(errors.New("reject your own pull is not allowed"))) return -1, true } reviewType = issues_model.ReviewTypeReject @@ -717,7 +717,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest needsBody = false // if there is no body we need to ensure that there are comments if !hasBody && !hasComments { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("review event %s requires a body or a comment", event)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("review event %s requires a body or a comment", event))) return -1, true } default: @@ -726,7 +726,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest // reject reviews with empty body if a body is required for this call if needsBody && !hasBody { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("review event %s requires a body", event)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("review event %s requires a body", event))) return -1, true } @@ -935,11 +935,11 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions comment, err := issue_service.ReviewRequest(ctx, pr.Issue, ctx.Doer, &permDoer, reviewer, isAdd) if err != nil { if issues_model.IsErrReviewRequestOnClosedPR(err) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) return } if issues_model.IsErrNotValidReviewRequest(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -960,11 +960,11 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions comment, err := issue_service.TeamReviewRequest(ctx, pr.Issue, ctx.Doer, teamReviewer, isAdd) if err != nil { if issues_model.IsErrReviewRequestOnClosedPR(err) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) return } if issues_model.IsErrNotValidReviewRequest(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -1086,7 +1086,7 @@ func UnDismissPullReview(ctx *context.APIContext) { func dismissReview(ctx *context.APIContext, msg string, isDismiss, dismissPriors bool) { if !ctx.Repo.Permission.IsAdmin() { - ctx.APIError(http.StatusForbidden, "Must be repo admin") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Must be repo admin")) return } review, _, isWrong := prepareSingleReview(ctx) @@ -1095,14 +1095,14 @@ func dismissReview(ctx *context.APIContext, msg string, isDismiss, dismissPriors } if review.Type != issues_model.ReviewTypeApprove && review.Type != issues_model.ReviewTypeReject { - ctx.APIError(http.StatusForbidden, "not need to dismiss this review because it's type is not Approve or change request") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("not need to dismiss this review because it's type is not Approve or change request")) return } _, err := pull_service.DismissReview(ctx, review.ID, ctx.Repo.Repository.ID, msg, ctx.Doer, isDismiss, dismissPriors) if err != nil { if pull_service.IsErrDismissRequestOnClosedPR(err) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index ee995f4402b..f4809812709 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -243,7 +243,7 @@ func CreateRelease(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.CreateReleaseOption) if ctx.Repo.Repository.IsEmpty { - ctx.APIError(http.StatusUnprocessableEntity, errors.New("repo is empty")) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(errors.New("repo is empty"))) return } rel, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, form.TagName) @@ -273,11 +273,11 @@ func CreateRelease(ctx *context.APIContext) { // It doesn't need to be the same as the "release note" if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, nil, form.TagMessage); err != nil { if repo_model.IsErrReleaseAlreadyExist(err) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) } else if release_service.IsErrProtectedTagName(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else if git.IsErrNotExist(err) { - ctx.APIError(http.StatusNotFound, fmt.Errorf("target \"%v\" not found: %w", rel.Target, err)) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(fmt.Errorf("target \"%v\" not found: %w", rel.Target, err))) } else { ctx.APIErrorInternal(err) } @@ -285,7 +285,7 @@ func CreateRelease(ctx *context.APIContext) { } } else { if !rel.IsTag { - ctx.APIError(http.StatusConflict, "Release is has no Tag") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("Release is has no Tag")) return } @@ -433,7 +433,7 @@ func DeleteRelease(ctx *context.APIContext) { } if err := release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, rel, ctx.Doer, false); err != nil { if release_service.IsErrProtectedTagName(err) { - ctx.APIError(http.StatusUnprocessableEntity, "user not allowed to delete protected tag") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("user not allowed to delete protected tag")) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index 896c6d24ccb..14f7b3cd978 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -237,7 +237,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) { } if filename == "" { - ctx.APIError(http.StatusBadRequest, "Could not determine name of attachment.") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Could not determine name of attachment.")) return } @@ -250,12 +250,12 @@ func CreateReleaseAttachment(ctx *context.APIContext) { }) if err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } if errors.Is(err, util.ErrContentTooLarge) { - ctx.APIError(http.StatusRequestEntityTooLarge, err) + ctx.APIError(http.StatusRequestEntityTooLarge, ctx.APIErrorMessage(err)) return } @@ -340,7 +340,7 @@ func EditReleaseAttachment(ctx *context.APIContext) { if err := attachment_service.UpdateAttachment(ctx, setting.Repository.Release.AllowedTypes, attach); err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go index 65338607c56..5f2fa893212 100644 --- a/routers/api/v1/repo/release_tags.go +++ b/routers/api/v1/repo/release_tags.go @@ -121,7 +121,7 @@ func DeleteReleaseByTag(ctx *context.APIContext) { if err = release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, release, ctx.Doer, false); err != nil { if release_service.IsErrProtectedTagName(err) { - ctx.APIError(http.StatusUnprocessableEntity, "user not allowed to delete protected tag") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("user not allowed to delete protected tag")) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index e0e40086a56..1e7596fea7c 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -173,7 +173,7 @@ func Search(ctx *context.APIContext) { opts.Collaborate = optional.Some(true) case "": default: - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid search mode: \"%s\"", mode)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("Invalid search mode: \"%s\"", mode))) return } @@ -234,7 +234,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre // If the readme template does not exist, a 400 will be returned. if opt.AutoInit && len(opt.Readme) > 0 && !slices.Contains(repo_module.Readmes, opt.Readme) { - ctx.APIError(http.StatusBadRequest, fmt.Errorf("readme template does not exist, available templates: %v", repo_module.Readmes)) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(fmt.Errorf("readme template does not exist, available templates: %v", repo_module.Readmes))) return } @@ -254,13 +254,13 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre }) if err != nil { if repo_model.IsErrRepoAlreadyExist(err) { - ctx.APIError(http.StatusConflict, "The repository with the same name already exists.") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("The repository with the same name already exists.")) } else if db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || label.IsErrTemplateLoad(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrPermissionDenied) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -302,7 +302,7 @@ func Create(ctx *context.APIContext) { opt := web.GetForm(ctx).(*api.CreateRepoOption) if ctx.Doer.IsOrganization() { // Shouldn't reach this condition, but just in case. - ctx.APIError(http.StatusUnprocessableEntity, "not allowed creating repository for organization") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("not allowed creating repository for organization")) return } CreateUserRepo(ctx, ctx.Doer, *opt) @@ -346,12 +346,12 @@ func Generate(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.GenerateRepoOption) if !ctx.Repo.Repository.IsTemplate { - ctx.APIError(http.StatusUnprocessableEntity, "this is not a template repo") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("this is not a template repo")) return } if ctx.Doer.IsOrganization() { - ctx.APIError(http.StatusUnprocessableEntity, "not allowed creating repository for organization") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("not allowed creating repository for organization")) return } @@ -370,7 +370,7 @@ func Generate(ctx *context.APIContext) { } if !opts.IsValid() { - ctx.APIError(http.StatusUnprocessableEntity, "must select at least one template item") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("must select at least one template item")) return } @@ -391,7 +391,7 @@ func Generate(ctx *context.APIContext) { } if !ctx.Doer.IsAdmin && !ctxUser.IsOrganization() { - ctx.APIError(http.StatusForbidden, "Only admin can generate repository for other user.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Only admin can generate repository for other user.")) return } @@ -401,7 +401,7 @@ func Generate(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if !canCreate { - ctx.APIError(http.StatusForbidden, "Given user is not allowed to create repository in organization.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Given user is not allowed to create repository in organization.")) return } } @@ -410,10 +410,10 @@ func Generate(ctx *context.APIContext) { repo, err := repo_service.GenerateRepository(ctx, ctx.Doer, ctxUser, ctx.Repo.Repository, opts) if err != nil { if repo_model.IsErrRepoAlreadyExist(err) { - ctx.APIError(http.StatusConflict, "The repository with the same name already exists.") + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage("The repository with the same name already exists.")) } else if db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -652,13 +652,13 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err if err := repo_service.ChangeRepositoryName(ctx, ctx.Doer, repo, newRepoName); err != nil { switch { case repo_model.IsErrRepoAlreadyExist(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) case db.IsErrNameReserved(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) case db.IsErrNamePatternNotAllowed(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) default: - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("ChangeRepositoryName: %w", err)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("ChangeRepositoryName: %w", err))) } return err } @@ -692,7 +692,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err // when ForcePrivate enabled, you could change public repo to private, but only admin users can change private to public if visibilityChanged && setting.Repository.ForcePrivate && !*opts.Private && !ctx.Doer.IsAdmin { err := errors.New("cannot change private repository to public") - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return err } @@ -756,12 +756,12 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { // Check that values are valid if !validation.IsValidURL(opts.ExternalTracker.ExternalTrackerURL) { err := errors.New("External tracker URL not valid") - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return err } if len(opts.ExternalTracker.ExternalTrackerFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(opts.ExternalTracker.ExternalTrackerFormat) { err := errors.New("External tracker URL format not valid") - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return err } @@ -818,7 +818,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { // Check that values are valid if !validation.IsValidURL(opts.ExternalWiki.ExternalWikiURL) { err := errors.New("External wiki URL not valid") - ctx.APIError(http.StatusUnprocessableEntity, "Invalid external wiki URL") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Invalid external wiki URL")) return err } @@ -897,7 +897,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { // so unrelated PATCH calls don't reject historical configs. if opts.AllowMergeUpdate != nil || opts.AllowRebaseUpdate != nil || opts.DefaultUpdateStyle != nil { if err := config.ValidateUpdateSettings(); err != nil { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return err } } @@ -988,7 +988,7 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e if opts.Archived != nil { if repo.IsMirror { err := errors.New("repo is a mirror, cannot archive/un-archive") - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return err } if *opts.Archived { @@ -1042,14 +1042,14 @@ func updateMirror(ctx *context.APIContext, opts api.EditRepoOption) error { interval, err := time.ParseDuration(*opts.MirrorInterval) if err != nil { log.Error("Wrong format for MirrorInternal Sent: %s", err) - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return err } // Ensure the provided duration is not too short if interval != 0 && interval < setting.Mirror.MinInterval { err := fmt.Errorf("invalid mirror interval: %s is below minimum interval: %s", interval, setting.Mirror.MinInterval) - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return err } @@ -1119,7 +1119,7 @@ func updateMirror(ctx *context.APIContext, opts api.EditRepoOption) error { // finally update the mirror in the DB if err := repo_model.UpdateMirror(ctx, mirror); err != nil { log.Error("Failed to Set Mirror Interval: %s", err) - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return err } @@ -1160,7 +1160,7 @@ func Delete(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if !canDelete { - ctx.APIError(http.StatusForbidden, "Given user is not owner of organization.") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Given user is not owner of organization.")) return } diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index 9df2a32e72d..6f6f369033f 100644 --- a/routers/api/v1/repo/status.go +++ b/routers/api/v1/repo/status.go @@ -55,7 +55,7 @@ func NewCommitStatus(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.CreateStatusOption) sha := ctx.PathParam("sha") if len(sha) == 0 { - ctx.APIError(http.StatusBadRequest, nil) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(nil)) return } status := &git_model.CommitStatus{ diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index 796bdb10883..0bd98464cd2 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -103,19 +103,19 @@ func GetAnnotatedTag(ctx *context.APIContext) { sha := ctx.PathParam("sha") if len(sha) == 0 { - ctx.APIError(http.StatusBadRequest, "SHA not provided") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("SHA not provided")) return } tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } commit, err := ctx.Repo.GitRepo.GetTagCommit(tag.Name) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx, ctx.Repo.Repository, tag, commit)) @@ -203,17 +203,17 @@ func CreateTag(ctx *context.APIContext) { commit, err := ctx.Repo.GitRepo.GetCommit(form.Target) if err != nil { - ctx.APIError(http.StatusNotFound, fmt.Errorf("target not found: %w", err)) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(fmt.Errorf("target not found: %w", err))) return } if err := release_service.CreateNewTag(ctx, ctx.Doer, ctx.Repo.Repository, commit.ID.String(), form.TagName, form.Message); err != nil { if release_service.IsErrTagAlreadyExists(err) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) return } if release_service.IsErrProtectedTagName(err) { - ctx.APIError(http.StatusUnprocessableEntity, "user not allowed to create protected tag") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("user not allowed to create protected tag")) return } @@ -278,13 +278,13 @@ func DeleteTag(ctx *context.APIContext) { } if !tag.IsTag { - ctx.APIError(http.StatusConflict, errors.New("a tag attached to a release cannot be deleted directly")) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(errors.New("a tag attached to a release cannot be deleted directly"))) return } if err = release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, tag, ctx.Doer, true); err != nil { if release_service.IsErrProtectedTagName(err) { - ctx.APIError(http.StatusUnprocessableEntity, "user not allowed to delete protected tag") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("user not allowed to delete protected tag")) return } ctx.APIErrorInternal(err) @@ -416,12 +416,12 @@ func CreateTagProtection(ctx *context.APIContext) { namePattern := strings.TrimSpace(form.NamePattern) if namePattern == "" { - ctx.APIError(http.StatusBadRequest, "name_pattern are empty") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("name_pattern are empty")) return } if len(form.WhitelistUsernames) == 0 && len(form.WhitelistTeams) == 0 { - ctx.APIError(http.StatusBadRequest, "both whitelist_usernames and whitelist_teams are empty") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("both whitelist_usernames and whitelist_teams are empty")) return } @@ -430,7 +430,7 @@ func CreateTagProtection(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if pt != nil { - ctx.APIError(http.StatusForbidden, "Tag protection already exist") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("Tag protection already exist")) return } @@ -438,7 +438,7 @@ func CreateTagProtection(ctx *context.APIContext) { whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.WhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -449,7 +449,7 @@ func CreateTagProtection(ctx *context.APIContext) { whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.WhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -546,7 +546,7 @@ func EditTagProtection(ctx *context.APIContext) { whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.WhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) @@ -560,7 +560,7 @@ func EditTagProtection(ctx *context.APIContext) { whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.WhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go index 1913bb6eecd..11d392c6b35 100644 --- a/routers/api/v1/repo/teams.go +++ b/routers/api/v1/repo/teams.go @@ -38,7 +38,7 @@ func ListTeams(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !ctx.Repo.Owner.IsOrganization() { - ctx.APIError(http.StatusMethodNotAllowed, "repo is not owned by an organization") + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage("repo is not owned by an organization")) return } @@ -89,7 +89,7 @@ func IsTeam(ctx *context.APIContext) { // "$ref": "#/responses/error" if !ctx.Repo.Owner.IsOrganization() { - ctx.APIError(http.StatusMethodNotAllowed, "repo is not owned by an organization") + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage("repo is not owned by an organization")) return } @@ -185,10 +185,10 @@ func DeleteTeam(ctx *context.APIContext) { func changeRepoTeam(ctx *context.APIContext, add bool) { if !ctx.Repo.Owner.IsOrganization() { - ctx.APIError(http.StatusMethodNotAllowed, "repo is not owned by an organization") + ctx.APIError(http.StatusMethodNotAllowed, ctx.APIErrorMessage("repo is not owned by an organization")) } if !ctx.Repo.Owner.RepoAdminChangeTeamAccess && !ctx.Repo.Permission.IsOwner() { - ctx.APIError(http.StatusForbidden, "user is nor repo admin nor owner") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("user is nor repo admin nor owner")) return } @@ -201,13 +201,13 @@ func changeRepoTeam(ctx *context.APIContext, add bool) { var err error if add { if repoHasTeam { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("team '%s' is already added to repo", team.Name)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("team '%s' is already added to repo", team.Name))) return } err = repo_service.TeamAddRepository(ctx, team, ctx.Repo.Repository) } else { if !repoHasTeam { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("team '%s' was not added to repo", team.Name)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("team '%s' was not added to repo", team.Name))) return } err = repo_service.RemoveRepositoryFromTeam(ctx, team, ctx.Repo.Repository.ID) @@ -224,7 +224,7 @@ func getTeamByParam(ctx *context.APIContext) *organization.Team { team, err := organization.GetTeam(ctx, ctx.Repo.Owner.ID, ctx.PathParam("team")) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) return nil } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go index e2c124a86a5..0b5db6ac25f 100644 --- a/routers/api/v1/repo/transfer.go +++ b/routers/api/v1/repo/transfer.go @@ -61,7 +61,7 @@ func Transfer(ctx *context.APIContext) { newOwner, err := user_model.GetUserByName(ctx, opts.NewOwner) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusNotFound, "The new owner does not exist or cannot be found") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("The new owner does not exist or cannot be found")) return } ctx.APIErrorInternal(err) @@ -71,7 +71,7 @@ func Transfer(ctx *context.APIContext) { if newOwner.Type == user_model.UserTypeOrganization { if !ctx.Doer.IsAdmin && newOwner.Visibility == api.VisibleTypePrivate && !organization.OrgFromUser(newOwner).HasMemberWithUserID(ctx, ctx.Doer.ID) { // The user shouldn't know about this organization - ctx.APIError(http.StatusNotFound, "The new owner does not exist or cannot be found") + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("The new owner does not exist or cannot be found")) return } } @@ -79,7 +79,7 @@ func Transfer(ctx *context.APIContext) { var teams []*organization.Team if opts.TeamIDs != nil { if !newOwner.IsOrganization() { - ctx.APIError(http.StatusUnprocessableEntity, "Teams can only be added to organization-owned repositories") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Teams can only be added to organization-owned repositories")) return } @@ -87,12 +87,12 @@ func Transfer(ctx *context.APIContext) { for _, tID := range *opts.TeamIDs { team, err := organization.GetTeamByID(ctx, tID) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("team %d not found", tID)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("team %d not found", tID))) return } if team.OrgID != org.ID { - ctx.APIError(http.StatusForbidden, fmt.Errorf("team %d belongs not to org %d", tID, org.ID)) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(fmt.Errorf("team %d belongs not to org %d", tID, org.ID))) return } @@ -110,13 +110,13 @@ func Transfer(ctx *context.APIContext) { if err := repo_service.StartRepositoryTransfer(ctx, ctx.Doer, newOwner, ctx.Repo.Repository, teams); err != nil { switch { case repo_model.IsErrRepoTransferInProgress(err): - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(err)) case repo_model.IsErrRepoAlreadyExist(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) case repo_service.IsRepositoryLimitReached(err): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) case errors.Is(err, user_model.ErrBlockedUser): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) default: ctx.APIErrorInternal(err) } @@ -163,11 +163,11 @@ func AcceptTransfer(ctx *context.APIContext) { if err != nil { switch { case repo_model.IsErrNoPendingTransfer(err): - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) case errors.Is(err, util.ErrPermissionDenied): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) case repo_service.IsRepositoryLimitReached(err): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) default: ctx.APIErrorInternal(err) } @@ -207,9 +207,9 @@ func RejectTransfer(ctx *context.APIContext) { if err != nil { switch { case repo_model.IsErrNoPendingTransfer(err): - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) case errors.Is(err, util.ErrPermissionDenied): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) default: ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go index 7c41a0e86d9..abe6d7d5ebe 100644 --- a/routers/api/v1/repo/tree.go +++ b/routers/api/v1/repo/tree.go @@ -58,11 +58,11 @@ func GetTree(ctx *context.APIContext) { sha := ctx.PathParam("sha") if len(sha) == 0 { - ctx.APIError(http.StatusBadRequest, "sha not provided") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("sha not provided")) return } if tree, err := files_service.GetTreeBySHA(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, sha, ctx.FormInt("page"), ctx.FormInt("per_page"), ctx.FormBool("recursive")); err != nil { - ctx.APIError(http.StatusBadRequest, err.Error()) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err.Error())) } else { ctx.SetTotalCountHeader(int64(tree.TotalCount)) ctx.JSON(http.StatusOK, tree) diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index 16471044820..d0d9f40ada5 100644 --- a/routers/api/v1/repo/wiki.go +++ b/routers/api/v1/repo/wiki.go @@ -59,7 +59,7 @@ func NewWikiPage(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.CreateWikiPageOptions) if util.IsEmptyString(form.Title) { - ctx.APIError(http.StatusBadRequest, nil) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(nil)) return } @@ -71,16 +71,16 @@ func NewWikiPage(ctx *context.APIContext) { content, err := base64.StdEncoding.DecodeString(form.ContentBase64) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } form.ContentBase64 = string(content) if err := wiki_service.AddWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName, form.ContentBase64, form.Message); err != nil { if repo_model.IsErrWikiReservedName(err) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if repo_model.IsErrWikiAlreadyExist(err) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -149,7 +149,7 @@ func EditWikiPage(ctx *context.APIContext) { content, err := base64.StdEncoding.DecodeString(form.ContentBase64) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } form.ContentBase64 = string(content) diff --git a/routers/api/v1/shared/action.go b/routers/api/v1/shared/action.go index 3dbe7008bec..26549e7f694 100644 --- a/routers/api/v1/shared/action.go +++ b/routers/api/v1/shared/action.go @@ -53,7 +53,7 @@ func ListJobs(ctx *context.APIContext, ownerID, repoID, runID int64, runAttemptI for _, status := range ctx.FormStrings("status") { values, err := convertToInternal(status) if err != nil { - ctx.APIError(http.StatusBadRequest, fmt.Errorf("Invalid status %s", status)) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(fmt.Errorf("Invalid status %s", status))) return } opts.Statuses = append(opts.Statuses, values...) @@ -155,7 +155,7 @@ func ListRuns(ctx *context.APIContext, ownerID, repoID int64) { for _, status := range ctx.FormStrings("status") { values, err := convertToInternal(status) if err != nil { - ctx.APIError(http.StatusBadRequest, fmt.Errorf("Invalid status %s", status)) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(fmt.Errorf("Invalid status %s", status))) return } opts.Status = append(opts.Status, values...) diff --git a/routers/api/v1/shared/block.go b/routers/api/v1/shared/block.go index e8190041aa5..2b68ac7824e 100644 --- a/routers/api/v1/shared/block.go +++ b/routers/api/v1/shared/block.go @@ -68,7 +68,7 @@ func BlockUser(ctx *context.APIContext, blocker *user_model.User) { if err := user_service.BlockUser(ctx, ctx.Doer, blocker, blockee, ctx.FormString("note")); err != nil { if errors.Is(err, user_model.ErrCanNotBlock) || errors.Is(err, user_model.ErrBlockOrganization) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -87,7 +87,7 @@ func UnblockUser(ctx *context.APIContext, doer, blocker *user_model.User) { if err := user_service.UnblockUser(ctx, doer, blocker, blockee); err != nil { if errors.Is(err, user_model.ErrCanNotUnblock) || errors.Is(err, user_model.ErrBlockOrganization) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/shared/runners.go b/routers/api/v1/shared/runners.go index 329f17736eb..089416d0eaa 100644 --- a/routers/api/v1/shared/runners.go +++ b/routers/api/v1/shared/runners.go @@ -137,7 +137,7 @@ func UpdateRunner(ctx *context.APIContext, ownerID, repoID, runnerID int64) { form := web.GetForm(ctx).(*api.EditActionRunnerOption) if form.Disabled == nil { - ctx.APIError(http.StatusUnprocessableEntity, "[Disabled]: Required") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("[Disabled]: Required")) return } diff --git a/routers/api/v1/user/action.go b/routers/api/v1/user/action.go index f5654908f0d..b26524678d1 100644 --- a/routers/api/v1/user/action.go +++ b/routers/api/v1/user/action.go @@ -53,9 +53,9 @@ func CreateOrUpdateSecret(ctx *context.APIContext) { _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Doer.ID, 0, ctx.PathParam("secretname"), opt.Data, opt.Description) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -95,9 +95,9 @@ func DeleteSecret(ctx *context.APIContext) { err := secret_service.DeleteSecretByName(ctx, ctx.Doer.ID, 0, ctx.PathParam("secretname")) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -148,13 +148,13 @@ func CreateVariable(ctx *context.APIContext) { return } if v != nil && v.ID > 0 { - ctx.APIError(http.StatusConflict, util.NewAlreadyExistErrorf("variable name %s already exists", variableName)) + ctx.APIError(http.StatusConflict, ctx.APIErrorMessage(util.NewAlreadyExistErrorf("variable name %s already exists", variableName))) return } if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value, opt.Description); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -201,7 +201,7 @@ func UpdateVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -218,7 +218,7 @@ func UpdateVariable(ctx *context.APIContext) { if _, err := actions_service.UpdateVariableNameData(ctx, v); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -253,9 +253,9 @@ func DeleteVariable(ctx *context.APIContext) { if err := actions_service.DeleteVariableByName(ctx, ctx.Doer.ID, 0, ctx.PathParam("variablename")); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } @@ -292,7 +292,7 @@ func GetVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go index 729c408a151..d5e2a57effe 100644 --- a/routers/api/v1/user/app.go +++ b/routers/api/v1/user/app.go @@ -112,17 +112,17 @@ func CreateAccessToken(ctx *context.APIContext) { return } if exist { - ctx.APIError(http.StatusBadRequest, errors.New("access token name has been used already")) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(errors.New("access token name has been used already"))) return } scope, err := auth_model.AccessTokenScope(strings.Join(form.Scopes, ",")).Normalize() if err != nil { - ctx.APIError(http.StatusBadRequest, fmt.Errorf("invalid access token scope provided: %w", err)) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(fmt.Errorf("invalid access token scope provided: %w", err))) return } if scope == "" { - ctx.APIError(http.StatusBadRequest, "access token must have a scope") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("access token must have a scope")) return } t.Scope = scope @@ -188,7 +188,7 @@ func DeleteAccessToken(ctx *context.APIContext) { case 1: tokenID = tokens[0].ID default: - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("multiple matches for token name '%s'", token)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("multiple matches for token name '%s'", token))) return } } @@ -230,7 +230,7 @@ func CreateOauth2Application(ctx *context.APIContext) { data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions) if invalidURI := forms.DetectInvalidOAuth2ApplicationRedirectURI(data.RedirectURIs); invalidURI != "" { - ctx.APIError(http.StatusBadRequest, "invalid redirect URI: "+invalidURI) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("invalid redirect URI: "+invalidURI)) return } app, err := auth_model.CreateOAuth2Application(ctx, auth_model.CreateOAuth2ApplicationOptions{ @@ -241,12 +241,12 @@ func CreateOauth2Application(ctx *context.APIContext) { SkipSecondaryAuthorization: data.SkipSecondaryAuthorization, }) if err != nil { - ctx.APIError(http.StatusBadRequest, "error creating oauth2 application") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("error creating oauth2 application")) return } secret, err := app.GenerateClientSecret(ctx) if err != nil { - ctx.APIError(http.StatusBadRequest, "error creating application secret") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("error creating application secret")) return } app.ClientSecret = secret @@ -394,7 +394,7 @@ func UpdateOauth2Application(ctx *context.APIContext) { data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions) if invalidURI := forms.DetectInvalidOAuth2ApplicationRedirectURI(data.RedirectURIs); invalidURI != "" { - ctx.APIError(http.StatusBadRequest, "invalid redirect URI: "+invalidURI) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("invalid redirect URI: "+invalidURI)) return } @@ -416,7 +416,7 @@ func UpdateOauth2Application(ctx *context.APIContext) { } app.ClientSecret, err = app.GenerateClientSecret(ctx) if err != nil { - ctx.APIError(http.StatusBadRequest, "error updating application secret") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("error updating application secret")) return } diff --git a/routers/api/v1/user/avatar.go b/routers/api/v1/user/avatar.go index d02ca87fb27..2d15a4e16ee 100644 --- a/routers/api/v1/user/avatar.go +++ b/routers/api/v1/user/avatar.go @@ -32,7 +32,7 @@ func UpdateAvatar(ctx *context.APIContext) { content, err := base64.StdEncoding.DecodeString(form.Image) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage(err)) return } diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go index 71b5a691c15..f730b7700ab 100644 --- a/routers/api/v1/user/email.go +++ b/routers/api/v1/user/email.go @@ -59,13 +59,13 @@ func AddEmail(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.CreateEmailOption) if len(form.Emails) == 0 { - ctx.APIError(http.StatusUnprocessableEntity, "Email list empty") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Email list empty")) return } if err := user_service.AddEmailAddresses(ctx, ctx.Doer, form.Emails); err != nil { if user_model.IsErrEmailAlreadyUsed(err) { - ctx.APIError(http.StatusUnprocessableEntity, "Email address has been used: "+err.(user_model.ErrEmailAlreadyUsed).Email) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Email address has been used: "+err.(user_model.ErrEmailAlreadyUsed).Email)) } else if user_model.IsErrEmailCharIsNotSupported(err) || user_model.IsErrEmailInvalid(err) { email := "" if typedError, ok := err.(user_model.ErrEmailInvalid); ok { @@ -76,7 +76,7 @@ func AddEmail(ctx *context.APIContext) { } errMsg := fmt.Sprintf("Email address %q invalid", email) - ctx.APIError(http.StatusUnprocessableEntity, errMsg) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(errMsg)) } else { ctx.APIErrorInternal(err) } @@ -122,7 +122,7 @@ func DeleteEmail(ctx *context.APIContext) { if err := user_service.DeleteEmailAddresses(ctx, ctx.Doer, form.Emails); err != nil { if user_model.IsErrEmailAddressNotExist(err) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go index 11f659c85a4..fd0f15ee838 100644 --- a/routers/api/v1/user/follower.go +++ b/routers/api/v1/user/follower.go @@ -233,7 +233,7 @@ func Follow(ctx *context.APIContext) { if err := user_model.FollowUser(ctx, ctx.Doer, ctx.ContextUser); err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go index bae4d7420f1..2d93b6eeb66 100644 --- a/routers/api/v1/user/gpg_key.go +++ b/routers/api/v1/user/gpg_key.go @@ -205,7 +205,7 @@ func VerifyUserGPGKey(ctx *context.APIContext) { if err != nil { if asymkey_model.IsErrGPGInvalidTokenSignature(err) { - ctx.APIError(http.StatusUnprocessableEntity, "The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: "+token) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: "+token)) return } ctx.APIErrorInternal(err) @@ -292,13 +292,13 @@ func DeleteGPGKey(ctx *context.APIContext) { func HandleAddGPGKeyError(ctx *context.APIContext, err error, token string) { switch { case asymkey_model.IsErrGPGKeyIDAlreadyUsed(err): - ctx.APIError(http.StatusUnprocessableEntity, "A key with the same id already exists") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("A key with the same id already exists")) case asymkey_model.IsErrGPGKeyParsing(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(err)) case asymkey_model.IsErrGPGNoEmailFound(err): - ctx.APIError(http.StatusNotFound, "None of the emails attached to the GPG key could be found. It may still be added if you provide a valid signature for the token: "+token) + ctx.APIError(http.StatusNotFound, ctx.APIErrorMessage("None of the emails attached to the GPG key could be found. It may still be added if you provide a valid signature for the token: "+token)) case asymkey_model.IsErrGPGInvalidTokenSignature(err): - ctx.APIError(http.StatusUnprocessableEntity, "The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: "+token) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: "+token)) default: ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go index 1a932c94af4..d93d0f78d42 100644 --- a/routers/api/v1/user/key.go +++ b/routers/api/v1/user/key.go @@ -287,13 +287,13 @@ func DeletePublicKey(ctx *context.APIContext) { } if externallyManaged { - ctx.APIError(http.StatusForbidden, "SSH Key is externally managed for this user") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("SSH Key is externally managed for this user")) return } if err := asymkey_service.DeletePublicKey(ctx, ctx.Doer, id); err != nil { if asymkey_model.IsErrKeyAccessDenied(err) { - ctx.APIError(http.StatusForbidden, "You do not have access to this key") + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage("You do not have access to this key")) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go index 7036a4f854b..8adb5466ca0 100644 --- a/routers/api/v1/user/star.go +++ b/routers/api/v1/user/star.go @@ -174,7 +174,7 @@ func Star(ctx *context.APIContext) { err := repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, true) if err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go index 94d3de84b8a..002921c8ec6 100644 --- a/routers/api/v1/user/watch.go +++ b/routers/api/v1/user/watch.go @@ -172,7 +172,7 @@ func Watch(ctx *context.APIContext) { err := repo_model.WatchRepo(ctx, ctx.Doer, ctx.Repo.Repository, true) if err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, ctx.APIErrorMessage(err)) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go index b0156b705a0..ad08cf7e3dc 100644 --- a/routers/api/v1/utils/hook.go +++ b/routers/api/v1/utils/hook.go @@ -81,21 +81,21 @@ func GetRepoHook(ctx *context.APIContext, repoID, hookID int64) (*webhook.Webhoo // write the appropriate error to `ctx`. Return whether the form is valid func checkCreateHookOption(ctx *context.APIContext, form *api.CreateHookOption) bool { if !webhook_service.IsValidHookTaskType(form.Type) { - ctx.APIError(http.StatusUnprocessableEntity, "Invalid hook type: "+form.Type) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Invalid hook type: "+form.Type)) return false } for _, name := range []string{"url", "content_type"} { if _, ok := form.Config[name]; !ok { - ctx.APIError(http.StatusUnprocessableEntity, "Missing config option: "+name) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Missing config option: "+name)) return false } } if !webhook.IsValidHookContentType(form.Config["content_type"]) { - ctx.APIError(http.StatusUnprocessableEntity, "Invalid content type") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Invalid content type")) return false } if !validation.IsValidURL(form.Config["url"]) { - ctx.APIError(http.StatusUnprocessableEntity, "Invalid url") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Invalid url")) return false } return true @@ -207,7 +207,7 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoI if form.Config["is_system_webhook"] != "" { sw, err := strconv.ParseBool(form.Config["is_system_webhook"]) if err != nil { - ctx.APIError(http.StatusUnprocessableEntity, "Invalid is_system_webhook value") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Invalid is_system_webhook value")) return nil, false } isSystemWebhook = sw @@ -237,13 +237,13 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoI if w.Type == webhook_module.SLACK { channel, ok := form.Config["channel"] if !ok { - ctx.APIError(http.StatusUnprocessableEntity, "Missing config option: channel") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Missing config option: channel")) return nil, false } channel = strings.TrimSpace(channel) if !webhook_service.IsValidSlackChannel(channel) { - ctx.APIError(http.StatusBadRequest, "Invalid slack channel name") + ctx.APIError(http.StatusBadRequest, ctx.APIErrorMessage("Invalid slack channel name")) return nil, false } @@ -341,14 +341,14 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh if form.Config != nil { if url, ok := form.Config["url"]; ok { if !validation.IsValidURL(url) { - ctx.APIError(http.StatusUnprocessableEntity, "Invalid url") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Invalid url")) return false } w.URL = url } if ct, ok := form.Config["content_type"]; ok { if !webhook.IsValidHookContentType(ct) { - ctx.APIError(http.StatusUnprocessableEntity, "Invalid content type") + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage("Invalid content type")) return false } w.ContentType = webhook.ToHookContentType(ct) diff --git a/routers/api/v1/utils/sort.go b/routers/api/v1/utils/sort.go index b5f819cdb6e..1dc81e17b7f 100644 --- a/routers/api/v1/utils/sort.go +++ b/routers/api/v1/utils/sort.go @@ -26,12 +26,12 @@ func ResolveSortOrder(ctx *context.APIContext, orderByMap map[string]map[string] } orderMap, ok := orderByMap[sortOrder] if !ok { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid sort order: %q", sortOrder)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("Invalid sort order: %q", sortOrder))) return "", false } orderBy, ok := orderMap[sortMode] if !ok { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid sort mode: %q", sortMode)) + ctx.APIError(http.StatusUnprocessableEntity, ctx.APIErrorMessage(fmt.Errorf("Invalid sort mode: %q", sortMode))) return "", false } return orderBy, true diff --git a/services/context/api.go b/services/context/api.go index 69d7c93c34c..231df5be973 100644 --- a/services/context/api.go +++ b/services/context/api.go @@ -155,6 +155,14 @@ func (ctx *APIContext) APIError(status int, msg string) { }) } +// APIErrorMessage converts any object to an API error message. +func (ctx *APIContext) APIErrorMessage(obj any) string { + if err, ok := obj.(error); ok { + return err.Error() + } + return fmt.Sprintf("%s", obj) +} + type apiContextKeyType struct{} var apiContextKey = apiContextKeyType{}