diff --git a/modules/markup/markdown/ast.go b/modules/markup/markdown/ast.go index f29f8837349..fae9d06e2a9 100644 --- a/modules/markup/markdown/ast.go +++ b/modules/markup/markdown/ast.go @@ -95,13 +95,13 @@ type Icon struct { // ColorPreview is an inline for a color preview type ColorPreview struct { ast.BaseInline - Color []byte + Color string } // Dump implements Node.Dump. func (n *ColorPreview) Dump(source []byte, level int) { m := map[string]string{} - m["Color"] = string(n.Color) + m["Color"] = n.Color ast.DumpHelper(n, source, level, m, nil) } @@ -114,7 +114,7 @@ func (n *ColorPreview) Kind() ast.NodeKind { } // NewColorPreview returns a new Span node. -func NewColorPreview(color []byte) *ColorPreview { +func NewColorPreview(color string) *ColorPreview { return &ColorPreview{ BaseInline: ast.BaseInline{}, Color: color, @@ -170,3 +170,14 @@ func (n *RawHTML) Kind() ast.NodeKind { func NewRawHTML(rawHTML template.HTML) *RawHTML { return &RawHTML{rawHTML: rawHTML} } + +func childSingleText(node ast.Node, source []byte) (string, bool) { + if node.FirstChild() == nil || node.FirstChild() != node.LastChild() { + return "", false + } + c, ok := node.FirstChild().(*ast.Text) + if !ok { + return "", false + } + return string(c.Segment.Value(source)), true +} diff --git a/modules/markup/markdown/transform_blockquote.go b/modules/markup/markdown/transform_blockquote.go index b6cbef9a0a8..2ec7cec9d5e 100644 --- a/modules/markup/markdown/transform_blockquote.go +++ b/modules/markup/markdown/transform_blockquote.go @@ -46,7 +46,10 @@ func (g *ASTTransformer) extractBlockquoteAttentionEmphasis(firstParagraph ast.N if !ok { return "", nil } - val1 := string(node1.Text(reader.Source())) //nolint:staticcheck // Text is deprecated + val1, ok := childSingleText(node1, reader.Source()) + if !ok { + return "", nil + } attentionType := strings.ToLower(val1) if g.attentionTypes.Contains(attentionType) { return attentionType, []ast.Node{node1} diff --git a/modules/markup/markdown/transform_codespan.go b/modules/markup/markdown/transform_codespan.go index 900c38b129e..df4a56fd9e5 100644 --- a/modules/markup/markdown/transform_codespan.go +++ b/modules/markup/markdown/transform_codespan.go @@ -39,7 +39,7 @@ func (r *HTMLRenderer) renderCodeSpan(w util.BufWriter, source []byte, n ast.Nod r.Writer.RawWrite(w, value) } case *ColorPreview: - _ = r.renderInternal.FormatWithSafeAttrs(w, ``, string(v.Color)) + _ = r.renderInternal.FormatWithSafeAttrs(w, ``, v.Color) } } return ast.WalkSkipChildren, nil @@ -68,8 +68,11 @@ func cssColorHandler(value string) bool { } func (g *ASTTransformer) transformCodeSpan(_ *markup.RenderContext, v *ast.CodeSpan, reader text.Reader) { - colorContent := v.Text(reader.Source()) //nolint:staticcheck // Text is deprecated - if cssColorHandler(string(colorContent)) { + colorContent, ok := childSingleText(v, reader.Source()) + if !ok { + return + } + if cssColorHandler(colorContent) { v.AppendChild(v, NewColorPreview(colorContent)) } } diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go index 6375748086c..4713c7a1c78 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index d7f10b75b0b..9441fe0c18e 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, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -97,14 +97,12 @@ 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, "PasswordIsRequired") return } if !password.IsComplexEnough(form.Password) { - err := errors.New("PasswordComplexity") - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, "PasswordComplexity") return } @@ -112,7 +110,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, "PasswordPwned") return } } @@ -143,7 +141,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, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -204,11 +202,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, fmt.Sprintf("password must be at least %d characters", setting.MinPasswordLength)) case errors.Is(err, password.ErrComplexity): - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, err.Error()) case errors.Is(err, password.ErrIsPwned), password.IsErrIsPwnedRequest(err): - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, err.Error()) default: ctx.APIErrorInternal(err) } @@ -222,9 +220,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, err.Error()) case user_model.IsErrEmailAlreadyUsed(err): - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, err.Error()) default: ctx.APIErrorInternal(err) } @@ -249,7 +247,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, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -289,13 +287,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, "target is an organization but not user") 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, "you cannot delete yourself") return } @@ -304,7 +302,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, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -471,13 +469,11 @@ func SearchUsers(ctx *context.APIContext) { var visible []api.VisibleType visibilityParam := ctx.FormString("visibility") - if len(visibilityParam) > 0 { - if visibility, ok := api.VisibilityModes[visibilityParam]; ok { - visible = []api.VisibleType{visibility} - } else { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid visibility: \"%s\"", visibilityParam)) - return - } + if visibility, ok := api.VisibilityModes[visibilityParam]; ok { + visible = []api.VisibleType{visibility} + } else if visibilityParam != "" { + ctx.APIError(http.StatusUnprocessableEntity, "invalid visibility") + return } searchOpts := user_model.SearchUserOptions{ @@ -551,7 +547,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, "target is an organization but not user") return } @@ -560,7 +556,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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index eb5f52fd575..4248faea5d4 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -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, "repo is archived") 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, "repo is not allowed to edit") return } } diff --git a/routers/api/v1/notify/notifications.go b/routers/api/v1/notify/notifications.go index 92aae46a784..8e032292c2e 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, err.Error()) 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, err.Error()) return nil } opts := &activities_model.FindNotificationOptions{ diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go index 16996907508..7ba4469ff66 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, err.Error()) return } if !tmpLastRead.IsZero() { diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go index 2b8c91169f8..c66db13f8b6 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, err.Error()) } 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, fmt.Sprintf("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..9894f577c54 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, err.Error()) return } if !tmpLastRead.IsZero() { diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go index d63a134bd55..3f1135dcf3f 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, err.Error()) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, err.Error()) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, err.Error()) } 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, err.Error()) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, "variable name already exists") 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, err.Error()) } 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, err.Error()) } 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/org/avatar.go b/routers/api/v1/org/avatar.go index 38b0655bea9..7e6f8a77c91 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, err.Error()) return } diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go index 4c3365e6a6d..443003d5de2 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, err.Error()) 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, err.Error()) return } l.Color = color diff --git a/routers/api/v1/org/member.go b/routers/api/v1/org/member.go index 957544d1047..11b46a05c1c 100644 --- a/routers/api/v1/org/member.go +++ b/routers/api/v1/org/member.go @@ -221,7 +221,7 @@ 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.APIErrorInternal(err) } else if !isOwner { ctx.APIError(http.StatusForbidden, "Cannot change member visibility") } diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index 87e847d6421..16d3e230a01 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, "not allowed to create org") 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, err.Error()) } 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, err.Error()) } 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, err.Error()) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index d8acc767c58..4373b90f2fa 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, err.Error()) } 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/packages/package.go b/routers/api/v1/packages/package.go index 6b01023ef91..d06d2a636b8 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.APIErrorNotFound() 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, err.Error()) } 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, err.Error()) } 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, err.Error()) case errors.Is(err, util.ErrPermissionDenied): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) 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, err.Error()) } 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, err.Error()) case errors.Is(err, util.ErrInvalidArgument): - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, err.Error()) default: ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 169ed4b68ec..5fc2e97d7a3 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, err.Error()) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, err.Error()) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, err.Error()) } 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, err.Error()) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, "variable name already exists") 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, err.Error()) } 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, err.Error()) } 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, err.Error()) } 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, err.Error()) } 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, err.Error()) } 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, "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, err.Error()) } else if errors.Is(err, util.ErrPermissionDenied) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) } else if errors.Is(err, util.ErrInvalidArgument) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) } 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, err.Error()) } 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, err.Error()) return } else if errors.Is(err, util.ErrAlreadyExist) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, err.Error()) return } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) 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, "runID must be a positive integer") return } diff --git a/routers/api/v1/repo/avatar.go b/routers/api/v1/repo/avatar.go index b3d52e16634..b00394ffcc5 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, err.Error()) return } diff --git a/routers/api/v1/repo/blob.go b/routers/api/v1/repo/blob.go index cd731b0d787..79b2dee245c 100644 --- a/routers/api/v1/repo/blob.go +++ b/routers/api/v1/repo/blob.go @@ -48,7 +48,7 @@ func GetBlob(ctx *context.APIContext) { } if blob, err := files_service.GetBlobBySHA(ctx.Repo.Repository, ctx.Repo.GitRepo, sha); err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, err.Error()) } else { ctx.JSON(http.StatusOK, blob) } diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 3afdf9694d1..3b6575d6763 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -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, "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, "branch protected") default: ctx.APIErrorInternal(err) } @@ -448,7 +448,7 @@ 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, err.Error()) case git.IsErrPushRejected(err): rej := err.(*git.ErrPushRejected) ctx.APIError(http.StatusForbidden, rej.Message) @@ -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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) return } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index b7938cb516d..e254d5e1289 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, err.Error()) } 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, err.Error()) } 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, err.Error()) } 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, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -284,7 +284,7 @@ func GetRepoPermissions(ctx *context.APIContext) { collaborator, err := user_model.GetUserByName(ctx, collaboratorUsername) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, "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..d83686083e5 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -217,7 +217,7 @@ func GetAllCommits(ctx *context.APIContext) { // get commit specified by sha baseCommit, err = ctx.Repo.GitRepo.GetCommit(sha) if err != nil { - ctx.NotFoundOrServerError(err) + ctx.APIErrorAuto(err) 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/download.go b/routers/api/v1/repo/download.go index d9470d143ea..0df406488c3 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, err.Error()) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 5f0659dc818..244d9393ce6 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -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, err.Error()) 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, err.Error()) 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, err.Error()) return } willCreate := apiOpts.SHA == "" @@ -584,17 +584,17 @@ func handleChangeRepoFilesError(ctx *context.APIContext, err error) { return } if files_service.IsErrUserCannotCommit(err) || pull_service.IsErrFilePathProtected(err) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) 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, err.Error()) return } if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index 9d95f538743..8943ad39931 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -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, err.Error()) } else if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 5d73cc3b312..a075c68f749 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, err.Error()) 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, err.Error()) } 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, err.Error()) return } @@ -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, repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name}.Error()) 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, err.Error()) } else if errors.Is(err, util.ErrPermissionDenied) || errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, err.Error()) } else { 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, issues_model.ErrIssueAlreadyChanged.Error()) 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, err.Error()) return } @@ -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, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/issue_attachment.go b/routers/api/v1/repo/issue_attachment.go index 00fa792771f..123f66399d4 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, err.Error()) } else if errors.Is(err, util.ErrContentTooLarge) { - ctx.APIError(http.StatusRequestEntityTooLarge, err) + ctx.APIError(http.StatusRequestEntityTooLarge, err.Error()) } 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, err.Error()) return } ctx.APIErrorInternal(err) @@ -336,7 +336,7 @@ func DeleteIssueAttachment(ctx *context.APIContext) { func getIssueFromContext(ctx *context.APIContext) *issues_model.Issue { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { - ctx.NotFoundOrServerError(err) + ctx.APIErrorAuto(err) return nil } @@ -361,7 +361,7 @@ func getIssueAttachmentSafeWrite(ctx *context.APIContext) *repo_model.Attachment func getIssueAttachmentSafeRead(ctx *context.APIContext, issue *issues_model.Issue) *repo_model.Attachment { attachment, err := repo_model.GetAttachmentByID(ctx, ctx.PathParamInt64("attachment_id")) if err != nil { - ctx.NotFoundOrServerError(err) + ctx.APIErrorAuto(err) return nil } if !attachmentBelongsToRepoOrIssue(ctx, attachment, issue) { diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 5b2d2084735..02a0f702ce9 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, err.Error()) 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, err.Error()) 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, err.Error()) 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.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, err.Error()) } 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, err.Error()) } 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..56d494190e4 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, err.Error()) } else if errors.Is(err, util.ErrContentTooLarge) { - ctx.APIError(http.StatusRequestEntityTooLarge, err) + ctx.APIError(http.StatusRequestEntityTooLarge, err.Error()) } 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, err.Error()) } 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, err.Error()) return } ctx.APIErrorInternal(err) @@ -346,7 +346,7 @@ func DeleteIssueCommentAttachment(ctx *context.APIContext) { func getIssueCommentSafe(ctx *context.APIContext) *issues_model.Comment { comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64("id")) if err != nil { - ctx.NotFoundOrServerError(err) + ctx.APIErrorAuto(err) return nil } if err := comment.LoadIssue(ctx); err != nil { @@ -391,7 +391,7 @@ func canUserWriteIssueCommentAttachment(ctx *context.APIContext, comment *issues func getIssueCommentAttachmentSafeRead(ctx *context.APIContext, comment *issues_model.Comment) *repo_model.Attachment { attachment, err := repo_model.GetAttachmentByID(ctx, ctx.PathParamInt64("attachment_id")) if err != nil { - ctx.NotFoundOrServerError(err) + ctx.APIErrorAuto(err) return nil } if !attachmentBelongsToRepoOrComment(ctx, attachment, comment) { diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index ecf42688615..c1bbbe29d00 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/issue_lock.go b/routers/api/v1/repo/issue_lock.go index 283b441fd20..75247593fd3 100644 --- a/routers/api/v1/repo/issue_lock.go +++ b/routers/api/v1/repo/issue_lock.go @@ -4,7 +4,6 @@ package repo import ( - "errors" "net/http" issues_model "gitea.dev/models/issues" @@ -63,7 +62,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, "no permission to lock this issue") return } @@ -130,7 +129,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, "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..c71649aeca4 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go index 3662e63c71b..c9fa39e93d2 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, "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, "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, err.Error()) } 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, "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, "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, err.Error()) } 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_subscription.go b/routers/api/v1/repo/issue_subscription.go index b2480e88a5a..84af3194df2 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, fmt.Sprintf("%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..1af649bfd79 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -4,7 +4,6 @@ package repo import ( - "errors" "net/http" "time" @@ -95,7 +94,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, err.Error()) } else if err != nil { ctx.APIErrorInternal(err) return @@ -104,7 +103,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, err.Error()) return } @@ -116,7 +115,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, "query by user not allowed; not enough rights") return } } @@ -286,7 +285,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, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -437,7 +436,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, "query by user not allowed; not enough rights") return } @@ -523,7 +522,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, err.Error()) } else if err != nil { ctx.APIErrorInternal(err) return @@ -533,7 +532,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, err.Error()) return } @@ -545,7 +544,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, "query by user not allowed; not enough rights") return } } @@ -607,7 +606,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, err.Error()) return } diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go index 44471a4f73f..b704bcee1d4 100644 --- a/routers/api/v1/repo/key.go +++ b/routers/api/v1/repo/key.go @@ -179,7 +179,7 @@ func HandleCheckKeyStringError(ctx *context.APIContext, err error) { } else if asymkey_model.IsErrKeyUnableVerify(err) { ctx.APIError(http.StatusUnprocessableEntity, "Unable to verify key content") } else { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid key content: %w", err)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid key content: %v", err)) } } diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go index aec82dce757..790a9212bc2 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, err.Error()) 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, err.Error()) return } l.Color = color diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go index 65ef10777c4..0e3e68d1e8b 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, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -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, "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, "the site administrator has disabled migrations") return } @@ -235,9 +235,9 @@ func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, err case db.IsErrNamePatternNotAllowed(err): ctx.APIError(http.StatusUnprocessableEntity, 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, err.Error()) case base.IsErrNotSupported(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) default: err = util.SanitizeErrorCredentialURLs(err) if strings.Contains(err.Error(), "Authentication failed") || diff --git a/routers/api/v1/repo/mirror.go b/routers/api/v1/repo/mirror.go index 53d47ff135e..c76946493ab 100644 --- a/routers/api/v1/repo/mirror.go +++ b/routers/api/v1/repo/mirror.go @@ -5,6 +5,7 @@ package repo import ( "errors" + "fmt" "net/http" "strings" "time" @@ -112,7 +113,7 @@ func PushMirrorSync(ctx *context.APIContext) { // 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, err.Error()) return } @@ -175,7 +176,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, err.Error()) return } @@ -239,7 +240,7 @@ func GetPushMirrorByName(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } else if !exist { - ctx.APIError(http.StatusNotFound, nil) + ctx.APIErrorNotFound() return } @@ -334,7 +335,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, err.Error()) return } ctx.Status(http.StatusNoContent) @@ -344,8 +345,12 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro repo := ctx.Repo.Repository interval, err := time.ParseDuration(mirrorOption.Interval) - if err != nil || (interval != 0 && interval < setting.Mirror.MinInterval) { - ctx.APIError(http.StatusBadRequest, err) + if err != nil { + ctx.APIError(http.StatusBadRequest, fmt.Sprintf("invalid interval: %v", err)) + return + } + if interval != 0 && interval < setting.Mirror.MinInterval { + ctx.APIError(http.StatusBadRequest, fmt.Sprintf("interval is shorter than minimum %v", setting.Mirror.MinInterval.String())) return } diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 6f6ba77fae0..54e7b78a1b4 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, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -448,7 +448,7 @@ func CreatePullRequest(ctx *context.APIContext) { HeadBranch: existingPr.HeadBranch, BaseBranch: existingPr.BaseBranch, } - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, err.Error()) return } @@ -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, repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}.Error()) 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, err.Error()) } else if errors.Is(err, user_model.ErrBlockedUser) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) } else if errors.Is(err, issues_model.ErrMustCollaborator) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) } 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, issues_model.ErrIssueAlreadyChanged.Error()) 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, err.Error()) return } @@ -721,7 +721,7 @@ func EditPullRequest(ctx *context.APIContext) { if user_model.IsErrUserNotExist(err) { ctx.APIError(http.StatusUnprocessableEntity, 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, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -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, fmt.Sprintf("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, err.Error()) return } else if issues_model.IsErrIssueIsClosed(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) return } else if pull_service.IsErrPullRequestHasMerged(err) { - ctx.APIError(http.StatusConflict, err) + ctx.APIError(http.StatusConflict, err.Error()) return } ctx.APIErrorInternal(err) @@ -977,11 +977,11 @@ func MergePullRequest(ctx *context.APIContext) { } else if errors.Is(err, pull_service.ErrNotMergeableState) { ctx.APIError(http.StatusMethodNotAllowed, "Please try again later") } else if errors.Is(err, pull_service.ErrNotReadyToMerge) { - ctx.APIError(http.StatusMethodNotAllowed, err) + ctx.APIError(http.StatusMethodNotAllowed, err.Error()) } else if asymkey_service.IsErrWontSign(err) { - ctx.APIError(http.StatusMethodNotAllowed, err) + ctx.APIError(http.StatusMethodNotAllowed, err.Error()) } else if errors.Is(err, pull_service.ErrHeadCommitsNotAllVerified) { - ctx.APIError(http.StatusMethodNotAllowed, err) + ctx.APIError(http.StatusMethodNotAllowed, err.Error()) } 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, fmt.Sprintf("%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, err.Error()) 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, err.Error()) 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, fmt.Sprintf("%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) @@ -1230,7 +1230,7 @@ func UpdatePullRequest(ctx *context.APIContext) { } if pr.HasMerged { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, "pull request is already merged") return } @@ -1240,7 +1240,7 @@ func UpdatePullRequest(ctx *context.APIContext) { } if pr.Issue.IsClosed { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, "pull request is already closed") return } diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index 901e6b69c08..54919cef90f 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -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, "no permission to delete comment") 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, err.Error()) } 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, "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, "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, err.Error()) } 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, "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, "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, fmt.Sprintf("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, fmt.Sprintf("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, err.Error()) return } if issues_model.IsErrNotValidReviewRequest(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) 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, err.Error()) return } if issues_model.IsErrNotValidReviewRequest(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) return } ctx.APIErrorInternal(err) @@ -1102,7 +1102,7 @@ func dismissReview(ctx *context.APIContext, msg string, isDismiss, dismissPriors _, 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, err.Error()) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index ee995f4402b..a4fc03ae321 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -4,8 +4,6 @@ package repo import ( - "errors" - "fmt" "net/http" auth_model "gitea.dev/models/auth" @@ -243,7 +241,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, "repo is empty") return } rel, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, form.TagName) @@ -273,11 +271,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, err.Error()) } else if release_service.IsErrProtectedTagName(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) } else if git.IsErrNotExist(err) { - ctx.APIError(http.StatusNotFound, fmt.Errorf("target \"%v\" not found: %w", rel.Target, err)) + ctx.APIError(http.StatusNotFound, "target not found") } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index 896c6d24ccb..715552d72c7 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -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, err.Error()) return } if errors.Is(err, util.ErrContentTooLarge) { - ctx.APIError(http.StatusRequestEntityTooLarge, err) + ctx.APIError(http.StatusRequestEntityTooLarge, err.Error()) 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, err.Error()) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index e0e40086a56..8adef610001 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, "invalid search 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, fmt.Sprintf("readme template does not exist, available templates: %v", repo_module.Readmes)) return } @@ -258,9 +258,9 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre } else if db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || label.IsErrTemplateLoad(err) { - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) } else if errors.Is(err, util.ErrPermissionDenied) { - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) } else { ctx.APIErrorInternal(err) } @@ -413,7 +413,7 @@ func Generate(ctx *context.APIContext) { ctx.APIError(http.StatusConflict, "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, err.Error()) } 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, err.Error()) case db.IsErrNameReserved(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) case db.IsErrNamePatternNotAllowed(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) default: - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("ChangeRepositoryName: %w", err)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("ChangeRepositoryName: %v", 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) return err } diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index 9df2a32e72d..c7d7014e541 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, "sha not provided") return } status := &git_model.CommitStatus{ diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index 796bdb10883..d43d5ea628b 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -109,13 +109,13 @@ func GetAnnotatedTag(ctx *context.APIContext) { tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, err.Error()) return } commit, err := ctx.Repo.GitRepo.GetTagCommit(tag.Name) if err != nil { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, err.Error()) return } ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx, ctx.Repo.Repository, tag, commit)) @@ -203,13 +203,13 @@ 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, fmt.Sprintf("target not found: %v", 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, err.Error()) return } if release_service.IsErrProtectedTagName(err) { @@ -278,7 +278,7 @@ 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, "a tag attached to a release cannot be deleted directly") 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, err.Error()) 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, err.Error()) 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, err.Error()) 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, err.Error()) return } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go index 1913bb6eecd..fc39b1c6166 100644 --- a/routers/api/v1/repo/teams.go +++ b/routers/api/v1/repo/teams.go @@ -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, fmt.Sprintf("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, fmt.Sprintf("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, err.Error()) return nil } ctx.APIErrorInternal(err) diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go index e2c124a86a5..63fc3b0712c 100644 --- a/routers/api/v1/repo/transfer.go +++ b/routers/api/v1/repo/transfer.go @@ -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, fmt.Sprintf("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, fmt.Sprintf("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, err.Error()) case repo_model.IsErrRepoAlreadyExist(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) case repo_service.IsRepositoryLimitReached(err): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) case errors.Is(err, user_model.ErrBlockedUser): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) 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, err.Error()) case errors.Is(err, util.ErrPermissionDenied): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) case repo_service.IsRepositoryLimitReached(err): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) 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, err.Error()) case errors.Is(err, util.ErrPermissionDenied): - ctx.APIError(http.StatusForbidden, err) + ctx.APIError(http.StatusForbidden, err.Error()) default: ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index 16471044820..dad0bfbbce0 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, "title is required") 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, err.Error()) 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, err.Error()) } else if repo_model.IsErrWikiAlreadyExist(err) { - ctx.APIError(http.StatusBadRequest, err) + ctx.APIError(http.StatusBadRequest, err.Error()) } 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, err.Error()) return } form.ContentBase64 = string(content) diff --git a/routers/api/v1/shared/action.go b/routers/api/v1/shared/action.go index 3dbe7008bec..5c95fa192c0 100644 --- a/routers/api/v1/shared/action.go +++ b/routers/api/v1/shared/action.go @@ -16,6 +16,7 @@ import ( "gitea.dev/modules/optional" "gitea.dev/modules/setting" api "gitea.dev/modules/structs" + "gitea.dev/modules/util" "gitea.dev/modules/webhook" "gitea.dev/routers/api/v1/utils" "gitea.dev/services/context" @@ -53,7 +54,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, err.Error()) return } opts.Statuses = append(opts.Statuses, values...) @@ -125,7 +126,7 @@ func convertToInternal(s string) ([]actions_model.Status, error) { case "cancelled", "timed_out": return []actions_model.Status{actions_model.StatusCancelled}, nil default: - return nil, fmt.Errorf("invalid status %s", s) + return nil, util.NewInvalidArgumentErrorf("invalid status %s", s) } } @@ -155,7 +156,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, err.Error()) 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..8b2a207ccb2 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, err.Error()) } 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/action.go b/routers/api/v1/user/action.go index f5654908f0d..1086b221924 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, err.Error()) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, err.Error()) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, "variable name already exists") 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, err.Error()) } 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, err.Error()) } 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, err.Error()) } 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, err.Error()) } else if errors.Is(err, util.ErrNotExist) { - ctx.APIError(http.StatusNotFound, err) + ctx.APIError(http.StatusNotFound, err.Error()) } 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go index 729c408a151..a410909e0e5 100644 --- a/routers/api/v1/user/app.go +++ b/routers/api/v1/user/app.go @@ -5,7 +5,6 @@ package user import ( - "errors" "fmt" "net/http" "strconv" @@ -112,13 +111,13 @@ 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, "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, fmt.Sprintf("invalid access token scope provided: %v", err)) return } if scope == "" { @@ -188,7 +187,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, fmt.Sprintf("multiple matches for token name '%s'", token)) return } } diff --git a/routers/api/v1/user/avatar.go b/routers/api/v1/user/avatar.go index d02ca87fb27..428ac0f62b7 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, err.Error()) return } diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go index 71b5a691c15..d3329f7a743 100644 --- a/routers/api/v1/user/email.go +++ b/routers/api/v1/user/email.go @@ -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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go index 11f659c85a4..47eabb5351d 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go index bae4d7420f1..562e70b5c0b 100644 --- a/routers/api/v1/user/gpg_key.go +++ b/routers/api/v1/user/gpg_key.go @@ -294,7 +294,7 @@ func HandleAddGPGKeyError(ctx *context.APIContext, err error, token string) { case asymkey_model.IsErrGPGKeyIDAlreadyUsed(err): ctx.APIError(http.StatusUnprocessableEntity, "A key with the same id already exists") case asymkey_model.IsErrGPGKeyParsing(err): - ctx.APIError(http.StatusUnprocessableEntity, err) + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) 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) case asymkey_model.IsErrGPGInvalidTokenSignature(err): diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go index 7036a4f854b..c78b6872c5a 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go index 94d3de84b8a..2d1f55d8709 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, err.Error()) } else { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/utils/sort.go b/routers/api/v1/utils/sort.go index b5f819cdb6e..669a09988ad 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, fmt.Sprintf("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, fmt.Sprintf("Invalid sort mode: %q", sortMode)) return "", false } return orderBy, true diff --git a/services/context/api.go b/services/context/api.go index 05b6490826a..7731b5692fc 100644 --- a/services/context/api.go +++ b/services/context/api.go @@ -137,16 +137,34 @@ func (ctx *APIContext) apiErrorInternal(skip int, err error) { }) } -// APIError responds with an error message to client with given obj as the message. -// If status is 500, also it prints error to log. -func (ctx *APIContext) APIError(status int, obj any) { +// APIErrorNotFound handles 404s for APIContext +// String will replace message, errors will be added to a slice +func (ctx *APIContext) APIErrorNotFound(objs ...any) { var message string - if err, ok := obj.(error); ok { - message = err.Error() - } else { - message = fmt.Sprintf("%s", obj) - } + var errs []string + for _, obj := range objs { + // Ignore nil + if obj == nil { + continue + } + if err, ok := obj.(error); ok { + errs = append(errs, err.Error()) + } else { + message = obj.(string) + } + } + ctx.JSON(http.StatusNotFound, map[string]any{ + "message": util.IfZero(message, "not found"), // do not use locale in API + "url": setting.API.SwaggerURL, + "errors": errs, + }) +} + +// APIError responds with an error message to client. +// If status is 500, also it prints error to log. +func (ctx *APIContext) APIError(status int, msg string) { + message := msg if status == http.StatusInternalServerError { log.ErrorWithSkip(1, "APIError: %s", message) @@ -161,6 +179,26 @@ func (ctx *APIContext) APIError(status int, obj any) { }) } +// APIErrorAuto use error check function to determine the response code +func (ctx *APIContext) APIErrorAuto(err error) { + switch { + case errors.Is(err, util.ErrInvalidArgument): + ctx.APIError(http.StatusBadRequest, err.Error()) + case errors.Is(err, util.ErrPermissionDenied): + ctx.APIError(http.StatusForbidden, err.Error()) + case errors.Is(err, util.ErrNotExist): + ctx.APIError(http.StatusNotFound, err.Error()) + case errors.Is(err, util.ErrAlreadyExist): + ctx.APIError(http.StatusConflict, err.Error()) + case errors.Is(err, util.ErrContentTooLarge): + ctx.APIError(http.StatusRequestEntityTooLarge, err.Error()) + case errors.Is(err, util.ErrUnprocessableContent): + ctx.APIError(http.StatusUnprocessableEntity, err.Error()) + default: + ctx.apiErrorInternal(1, err) + } +} + type apiContextKeyType struct{} var apiContextKey = apiContextKeyType{} @@ -248,30 +286,6 @@ func APIContexter() func(http.Handler) http.Handler { } } -// APIErrorNotFound handles 404s for APIContext -// String will replace message, errors will be added to a slice -func (ctx *APIContext) APIErrorNotFound(objs ...any) { - var message string - var errs []string - for _, obj := range objs { - // Ignore nil - if obj == nil { - continue - } - - if err, ok := obj.(error); ok { - errs = append(errs, err.Error()) - } else { - message = obj.(string) - } - } - ctx.JSON(http.StatusNotFound, map[string]any{ - "message": util.IfZero(message, "not found"), // do not use locale in API - "url": setting.API.SwaggerURL, - "errors": errs, - }) -} - // ReferencesGitRepo injects the GitRepo into the Context // you can optional skip the IsEmpty check func ReferencesGitRepo(allowEmpty ...bool) func(ctx *APIContext) { @@ -329,17 +343,6 @@ func RepoRefForAPI(next http.Handler) http.Handler { }) } -// NotFoundOrServerError use error check function to determine if the error -// is about not found. It responds with 404 status code for not found error, -// or error context description for logging purpose of 500 server error. -func (ctx *APIContext) NotFoundOrServerError(err error) { - if errors.Is(err, util.ErrNotExist) { - ctx.JSON(http.StatusNotFound, nil) - return - } - ctx.APIErrorInternal(err) -} - // IsUserSiteAdmin returns true if current user is a site admin func (ctx *APIContext) IsUserSiteAdmin() bool { return ctx.IsSigned && ctx.Doer.IsAdmin diff --git a/services/context/package.go b/services/context/package.go index 4918e124913..7c1e55c8a34 100644 --- a/services/context/package.go +++ b/services/context/package.go @@ -34,11 +34,8 @@ type packageAssignmentCtx struct { // PackageAssignment returns a middleware to handle Context.Package assignment func PackageAssignment() func(ctx *Context) { return func(ctx *Context) { - errorFn := func(status int, obj any) { - err, ok := obj.(error) - if !ok { - err = fmt.Errorf("%s", obj) - } + errorFn := func(status int, msg string) { + err := fmt.Errorf("%s", msg) if status == http.StatusNotFound { ctx.NotFound(err) } else { @@ -58,11 +55,11 @@ func PackageAssignmentAPI() func(ctx *APIContext) { } } -func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, any)) *Package { +func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, string)) *Package { pkgOwner := ctx.ContextUser accessMode, err := determineAccessMode(ctx.Base, pkgOwner, ctx.Doer) if err != nil { - errCb(http.StatusInternalServerError, fmt.Errorf("determineAccessMode: %w", err)) + errCb(http.StatusInternalServerError, fmt.Sprintf("determineAccessMode: %v", err)) return nil } @@ -81,25 +78,25 @@ func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, any)) *Package pv, err := packages_model.GetVersionByNameAndVersion(ctx, pkg.Owner.ID, packages_model.Type(packageType), name, version) if err != nil { if errors.Is(err, packages_model.ErrPackageNotExist) { - errCb(http.StatusNotFound, fmt.Errorf("GetVersionByNameAndVersion: %w", err)) + errCb(http.StatusNotFound, fmt.Sprintf("GetVersionByNameAndVersion: %v", err)) } else { - errCb(http.StatusInternalServerError, fmt.Errorf("GetVersionByNameAndVersion: %w", err)) + errCb(http.StatusInternalServerError, fmt.Sprintf("GetVersionByNameAndVersion: %v", err)) } return pkg } pkg.Descriptor, err = packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - errCb(http.StatusInternalServerError, fmt.Errorf("GetPackageDescriptor: %w", err)) + errCb(http.StatusInternalServerError, fmt.Sprintf("GetPackageDescriptor: %v", err)) return pkg } } else { p, err := packages_model.GetPackageByName(ctx, pkg.Owner.ID, packages_model.Type(packageType), name) if err != nil { if errors.Is(err, packages_model.ErrPackageNotExist) { - errCb(http.StatusNotFound, fmt.Errorf("GetPackageByName: %w", err)) + errCb(http.StatusNotFound, fmt.Sprintf("GetPackageByName: %v", err)) } else { - errCb(http.StatusInternalServerError, fmt.Errorf("GetPackageByName: %w", err)) + errCb(http.StatusInternalServerError, fmt.Sprintf("GetPackageByName: %v", err)) } return pkg } diff --git a/services/context/user.go b/services/context/user.go index ad0876ebf00..d335b9738a5 100644 --- a/services/context/user.go +++ b/services/context/user.go @@ -14,11 +14,8 @@ import ( // UserAssignmentWeb returns a middleware to handle context-user assignment for web routes func UserAssignmentWeb() func(ctx *Context) { return func(ctx *Context) { - errorFn := func(status int, obj any) { - err, ok := obj.(error) - if !ok { - err = fmt.Errorf("%s", obj) - } + errorFn := func(status int, msg string) { + err := fmt.Errorf("%s", msg) if status == http.StatusNotFound { ctx.NotFound(err) } else { @@ -37,7 +34,7 @@ func UserAssignmentAPI() func(ctx *APIContext) { } } -func userAssignment(ctx *Base, doer *user_model.User, errCb func(int, any)) (contextUser *user_model.User) { +func userAssignment(ctx *Base, doer *user_model.User, errCb func(int, string)) (contextUser *user_model.User) { username := ctx.PathParam("username") if doer != nil && strings.EqualFold(doer.LowerName, username) { @@ -50,12 +47,12 @@ func userAssignment(ctx *Base, doer *user_model.User, errCb func(int, any)) (con if redirectUserID, err := user_model.LookupUserRedirect(ctx, username); err == nil { RedirectToUser(ctx, doer, username, redirectUserID) } else if user_model.IsErrUserRedirectNotExist(err) { - errCb(http.StatusNotFound, err) + errCb(http.StatusNotFound, err.Error()) } else { - errCb(http.StatusInternalServerError, fmt.Errorf("LookupUserRedirect: %w", err)) + errCb(http.StatusInternalServerError, fmt.Sprintf("LookupUserRedirect: %v", err)) } } else { - errCb(http.StatusInternalServerError, fmt.Errorf("GetUserByName: %w", err)) + errCb(http.StatusInternalServerError, fmt.Sprintf("GetUserByName: %v", err)) } } }