diff --git a/Makefile b/Makefile index 67a4e27efc727..0b0d2afad6006 100644 --- a/Makefile +++ b/Makefile @@ -146,7 +146,7 @@ WEB_DIRS := web_src/js web_src/css ESLINT_FILES := web_src/js tools *.js *.ts *.cjs tests/e2e STYLELINT_FILES := web_src/css web_src/js/components/*.vue -SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) templates options/locale/locale_en-US.ini .github $(filter-out CHANGELOG.md, $(wildcard *.go *.js *.md *.yml *.yaml *.toml)) +SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) templates options/locale/locale_en-US.ini .github $(filter-out CHANGELOG.md, $(wildcard *.go *.js *.md *.yml *.yaml *.toml)) $(filter-out tools/misspellings.csv, $(wildcard tools/*)) EDITORCONFIG_FILES := templates .github/workflows options/locale/locale_en-US.ini GO_SOURCES := $(wildcard *.go) diff --git a/models/fixtures/issue_pin.yml b/models/fixtures/issue_pin.yml new file mode 100644 index 0000000000000..14b7a72d847bd --- /dev/null +++ b/models/fixtures/issue_pin.yml @@ -0,0 +1,6 @@ +- + id: 1 + repo_id: 2 + issue_id: 4 + is_pull: false + pin_order: 1 diff --git a/models/issues/issue.go b/models/issues/issue.go index 5d52f0dd5d7d3..7e72bb776c6b9 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -97,7 +97,7 @@ type Issue struct { // TODO: RemoveIssueRef: see "repo/issue/branch_selector_field.tmpl" Ref string - PinOrder int `xorm:"DEFAULT 0"` + PinOrder int `xorm:"-"` // 0 means not loaded, -1 means loaded but not pinned DeadlineUnix timeutil.TimeStamp `xorm:"INDEX"` @@ -291,6 +291,23 @@ func (issue *Issue) LoadMilestone(ctx context.Context) (err error) { return nil } +func (issue *Issue) LoadPinOrder(ctx context.Context) error { + if issue.PinOrder != 0 { + return nil + } + issuePin, err := GetIssuePin(ctx, issue) + if err != nil && !db.IsErrNotExist(err) { + return err + } + + if issuePin != nil { + issue.PinOrder = issuePin.PinOrder + } else { + issue.PinOrder = -1 + } + return nil +} + // LoadAttributes loads the attribute of this issue. func (issue *Issue) LoadAttributes(ctx context.Context) (err error) { if err = issue.LoadRepo(ctx); err != nil { @@ -330,6 +347,10 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) { return err } + if err = issue.LoadPinOrder(ctx); err != nil { + return err + } + if err = issue.Comments.LoadAttributes(ctx); err != nil { return err } @@ -342,6 +363,14 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) { return issue.loadReactions(ctx) } +// IsPinned returns if a Issue is pinned +func (issue *Issue) IsPinned() bool { + if issue.PinOrder == 0 { + setting.PanicInDevOrTesting("issue's pinorder has not been loaded") + } + return issue.PinOrder > 0 +} + func (issue *Issue) ResetAttributesLoaded() { issue.isLabelsLoaded = false issue.isMilestoneLoaded = false @@ -720,190 +749,6 @@ func (issue *Issue) HasOriginalAuthor() bool { return issue.OriginalAuthor != "" && issue.OriginalAuthorID != 0 } -var ErrIssueMaxPinReached = util.NewInvalidArgumentErrorf("the max number of pinned issues has been readched") - -// IsPinned returns if a Issue is pinned -func (issue *Issue) IsPinned() bool { - return issue.PinOrder != 0 -} - -// Pin pins a Issue -func (issue *Issue) Pin(ctx context.Context, user *user_model.User) error { - // If the Issue is already pinned, we don't need to pin it twice - if issue.IsPinned() { - return nil - } - - var maxPin int - _, err := db.GetEngine(ctx).SQL("SELECT MAX(pin_order) FROM issue WHERE repo_id = ? AND is_pull = ?", issue.RepoID, issue.IsPull).Get(&maxPin) - if err != nil { - return err - } - - // Check if the maximum allowed Pins reached - if maxPin >= setting.Repository.Issue.MaxPinned { - return ErrIssueMaxPinReached - } - - _, err = db.GetEngine(ctx).Table("issue"). - Where("id = ?", issue.ID). - Update(map[string]any{ - "pin_order": maxPin + 1, - }) - if err != nil { - return err - } - - // Add the pin event to the history - opts := &CreateCommentOptions{ - Type: CommentTypePin, - Doer: user, - Repo: issue.Repo, - Issue: issue, - } - if _, err = CreateComment(ctx, opts); err != nil { - return err - } - - return nil -} - -// UnpinIssue unpins a Issue -func (issue *Issue) Unpin(ctx context.Context, user *user_model.User) error { - // If the Issue is not pinned, we don't need to unpin it - if !issue.IsPinned() { - return nil - } - - // This sets the Pin for all Issues that come after the unpined Issue to the correct value - _, err := db.GetEngine(ctx).Exec("UPDATE issue SET pin_order = pin_order - 1 WHERE repo_id = ? AND is_pull = ? AND pin_order > ?", issue.RepoID, issue.IsPull, issue.PinOrder) - if err != nil { - return err - } - - _, err = db.GetEngine(ctx).Table("issue"). - Where("id = ?", issue.ID). - Update(map[string]any{ - "pin_order": 0, - }) - if err != nil { - return err - } - - // Add the unpin event to the history - opts := &CreateCommentOptions{ - Type: CommentTypeUnpin, - Doer: user, - Repo: issue.Repo, - Issue: issue, - } - if _, err = CreateComment(ctx, opts); err != nil { - return err - } - - return nil -} - -// PinOrUnpin pins or unpins a Issue -func (issue *Issue) PinOrUnpin(ctx context.Context, user *user_model.User) error { - if !issue.IsPinned() { - return issue.Pin(ctx, user) - } - - return issue.Unpin(ctx, user) -} - -// MovePin moves a Pinned Issue to a new Position -func (issue *Issue) MovePin(ctx context.Context, newPosition int) error { - // If the Issue is not pinned, we can't move them - if !issue.IsPinned() { - return nil - } - - if newPosition < 1 { - return fmt.Errorf("The Position can't be lower than 1") - } - - dbctx, committer, err := db.TxContext(ctx) - if err != nil { - return err - } - defer committer.Close() - - var maxPin int - _, err = db.GetEngine(dbctx).SQL("SELECT MAX(pin_order) FROM issue WHERE repo_id = ? AND is_pull = ?", issue.RepoID, issue.IsPull).Get(&maxPin) - if err != nil { - return err - } - - // If the new Position bigger than the current Maximum, set it to the Maximum - if newPosition > maxPin+1 { - newPosition = maxPin + 1 - } - - // Lower the Position of all Pinned Issue that came after the current Position - _, err = db.GetEngine(dbctx).Exec("UPDATE issue SET pin_order = pin_order - 1 WHERE repo_id = ? AND is_pull = ? AND pin_order > ?", issue.RepoID, issue.IsPull, issue.PinOrder) - if err != nil { - return err - } - - // Higher the Position of all Pinned Issues that comes after the new Position - _, err = db.GetEngine(dbctx).Exec("UPDATE issue SET pin_order = pin_order + 1 WHERE repo_id = ? AND is_pull = ? AND pin_order >= ?", issue.RepoID, issue.IsPull, newPosition) - if err != nil { - return err - } - - _, err = db.GetEngine(dbctx).Table("issue"). - Where("id = ?", issue.ID). - Update(map[string]any{ - "pin_order": newPosition, - }) - if err != nil { - return err - } - - return committer.Commit() -} - -// GetPinnedIssues returns the pinned Issues for the given Repo and type -func GetPinnedIssues(ctx context.Context, repoID int64, isPull bool) (IssueList, error) { - issues := make(IssueList, 0) - - err := db.GetEngine(ctx). - Table("issue"). - Where("repo_id = ?", repoID). - And("is_pull = ?", isPull). - And("pin_order > 0"). - OrderBy("pin_order"). - Find(&issues) - if err != nil { - return nil, err - } - - err = issues.LoadAttributes(ctx) - if err != nil { - return nil, err - } - - return issues, nil -} - -// IsNewPinAllowed returns if a new Issue or Pull request can be pinned -func IsNewPinAllowed(ctx context.Context, repoID int64, isPull bool) (bool, error) { - var maxPin int - _, err := db.GetEngine(ctx).SQL("SELECT COUNT(pin_order) FROM issue WHERE repo_id = ? AND is_pull = ? AND pin_order > 0", repoID, isPull).Get(&maxPin) - if err != nil { - return false, err - } - - return maxPin < setting.Repository.Issue.MaxPinned, nil -} - -// IsErrIssueMaxPinReached returns if the error is, that the User can't pin more Issues -func IsErrIssueMaxPinReached(err error) bool { - return err == ErrIssueMaxPinReached -} - // InsertIssues insert issues to database func InsertIssues(ctx context.Context, issues ...*Issue) error { ctx, committer, err := db.TxContext(ctx) diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go index 02fd330f0a7d8..6c74b533b3c54 100644 --- a/models/issues/issue_list.go +++ b/models/issues/issue_list.go @@ -506,6 +506,39 @@ func (issues IssueList) loadTotalTrackedTimes(ctx context.Context) (err error) { return nil } +func (issues IssueList) LoadPinOrder(ctx context.Context) error { + if len(issues) == 0 { + return nil + } + + issueIDs := container.FilterSlice(issues, func(issue *Issue) (int64, bool) { + return issue.ID, issue.PinOrder == 0 + }) + if len(issueIDs) == 0 { + return nil + } + issuePins, err := GetIssuePinsByIssueIDs(ctx, issueIDs) + if err != nil { + return err + } + + for _, issue := range issues { + if issue.PinOrder != 0 { + continue + } + for _, pin := range issuePins { + if pin.IssueID == issue.ID { + issue.PinOrder = pin.PinOrder + break + } + } + if issue.PinOrder == 0 { + issue.PinOrder = -1 + } + } + return nil +} + // loadAttributes loads all attributes, expect for attachments and comments func (issues IssueList) LoadAttributes(ctx context.Context) error { if _, err := issues.LoadRepositories(ctx); err != nil { diff --git a/models/issues/issue_pin.go b/models/issues/issue_pin.go new file mode 100644 index 0000000000000..ae6195b05ddac --- /dev/null +++ b/models/issues/issue_pin.go @@ -0,0 +1,246 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package issues + +import ( + "context" + "errors" + "sort" + + "code.gitea.io/gitea/models/db" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" +) + +type IssuePin struct { + ID int64 `xorm:"pk autoincr"` + RepoID int64 `xorm:"UNIQUE(s) NOT NULL"` + IssueID int64 `xorm:"UNIQUE(s) NOT NULL"` + IsPull bool `xorm:"NOT NULL"` + PinOrder int `xorm:"DEFAULT 0"` +} + +var ErrIssueMaxPinReached = util.NewInvalidArgumentErrorf("the max number of pinned issues has been readched") + +// IsErrIssueMaxPinReached returns if the error is, that the User can't pin more Issues +func IsErrIssueMaxPinReached(err error) bool { + return err == ErrIssueMaxPinReached +} + +func init() { + db.RegisterModel(new(IssuePin)) +} + +func GetIssuePin(ctx context.Context, issue *Issue) (*IssuePin, error) { + pin := new(IssuePin) + has, err := db.GetEngine(ctx). + Where("repo_id = ?", issue.RepoID). + And("issue_id = ?", issue.ID).Get(pin) + if err != nil { + return nil, err + } else if !has { + return nil, db.ErrNotExist{ + Resource: "IssuePin", + ID: issue.ID, + } + } + return pin, nil +} + +func GetIssuePinsByIssueIDs(ctx context.Context, issueIDs []int64) ([]IssuePin, error) { + var pins []IssuePin + if err := db.GetEngine(ctx).In("issue_id", issueIDs).Find(&pins); err != nil { + return nil, err + } + return pins, nil +} + +// Pin pins a Issue +func PinIssue(ctx context.Context, issue *Issue, user *user_model.User) error { + return db.WithTx(ctx, func(ctx context.Context) error { + pinnedIssuesNum, err := getPinnedIssuesNum(ctx, issue.RepoID, issue.IsPull) + if err != nil { + return err + } + + // Check if the maximum allowed Pins reached + if pinnedIssuesNum >= setting.Repository.Issue.MaxPinned { + return ErrIssueMaxPinReached + } + + pinnedIssuesMaxPinOrder, err := getPinnedIssuesMaxPinOrder(ctx, issue.RepoID, issue.IsPull) + if err != nil { + return err + } + + if _, err = db.GetEngine(ctx).Insert(&IssuePin{ + RepoID: issue.RepoID, + IssueID: issue.ID, + IsPull: issue.IsPull, + PinOrder: pinnedIssuesMaxPinOrder + 1, + }); err != nil { + return err + } + + // Add the pin event to the history + _, err = CreateComment(ctx, &CreateCommentOptions{ + Type: CommentTypePin, + Doer: user, + Repo: issue.Repo, + Issue: issue, + }) + return err + }) +} + +// UnpinIssue unpins a Issue +func UnpinIssue(ctx context.Context, issue *Issue, user *user_model.User) error { + return db.WithTx(ctx, func(ctx context.Context) error { + // This sets the Pin for all Issues that come after the unpined Issue to the correct value + cnt, err := db.GetEngine(ctx).Where("issue_id=?", issue.ID).Delete(new(IssuePin)) + if err != nil { + return err + } + if cnt == 0 { + return nil + } + + // Add the unpin event to the history + _, err = CreateComment(ctx, &CreateCommentOptions{ + Type: CommentTypeUnpin, + Doer: user, + Repo: issue.Repo, + Issue: issue, + }) + return err + }) +} + +func getPinnedIssuesNum(ctx context.Context, repoID int64, isPull bool) (int, error) { + var pinnedIssuesNum int + _, err := db.GetEngine(ctx).SQL("SELECT count(pin_order) FROM issue_pin WHERE repo_id = ? AND is_pull = ?", repoID, isPull).Get(&pinnedIssuesNum) + return pinnedIssuesNum, err +} + +func getPinnedIssuesMaxPinOrder(ctx context.Context, repoID int64, isPull bool) (int, error) { + var maxPinnedIssuesMaxPinOrder int + _, err := db.GetEngine(ctx).SQL("SELECT max(pin_order) FROM issue_pin WHERE repo_id = ? AND is_pull = ?", repoID, isPull).Get(&maxPinnedIssuesMaxPinOrder) + return maxPinnedIssuesMaxPinOrder, err +} + +// MovePin moves a Pinned Issue to a new Position +func MovePin(ctx context.Context, issue *Issue, newPosition int) error { + if newPosition < 1 { + return errors.New("The Position can't be lower than 1") + } + + issuePin, err := GetIssuePin(ctx, issue) + if err != nil { + return err + } + if issuePin.PinOrder == newPosition { + return nil + } + + return db.WithTx(ctx, func(ctx context.Context) error { + if issuePin.PinOrder > newPosition { // move the issue to a lower position + _, err = db.GetEngine(ctx).Exec("UPDATE issue_pin SET pin_order = pin_order + 1 WHERE repo_id = ? AND is_pull = ? AND pin_order >= ? AND pin_order < ?", issue.RepoID, issue.IsPull, newPosition, issuePin.PinOrder) + } else { // move the issue to a higher position + // Lower the Position of all Pinned Issue that came after the current Position + _, err = db.GetEngine(ctx).Exec("UPDATE issue_pin SET pin_order = pin_order - 1 WHERE repo_id = ? AND is_pull = ? AND pin_order > ? AND pin_order <= ?", issue.RepoID, issue.IsPull, issuePin.PinOrder, newPosition) + } + if err != nil { + return err + } + + _, err = db.GetEngine(ctx). + Table("issue_pin"). + Where("id = ?", issuePin.ID). + Update(map[string]any{ + "pin_order": newPosition, + }) + return err + }) +} + +func GetPinnedIssueIDs(ctx context.Context, repoID int64, isPull bool) ([]int64, error) { + var issuePins []IssuePin + if err := db.GetEngine(ctx). + Table("issue_pin"). + Where("repo_id = ?", repoID). + And("is_pull = ?", isPull). + Find(&issuePins); err != nil { + return nil, err + } + + sort.Slice(issuePins, func(i, j int) bool { + return issuePins[i].PinOrder < issuePins[j].PinOrder + }) + + var ids []int64 + for _, pin := range issuePins { + ids = append(ids, pin.IssueID) + } + return ids, nil +} + +func GetIssuePinsByRepoID(ctx context.Context, repoID int64, isPull bool) ([]*IssuePin, error) { + var pins []*IssuePin + if err := db.GetEngine(ctx).Where("repo_id = ? AND is_pull = ?", repoID, isPull).Find(&pins); err != nil { + return nil, err + } + return pins, nil +} + +// GetPinnedIssues returns the pinned Issues for the given Repo and type +func GetPinnedIssues(ctx context.Context, repoID int64, isPull bool) (IssueList, error) { + issuePins, err := GetIssuePinsByRepoID(ctx, repoID, isPull) + if err != nil { + return nil, err + } + if len(issuePins) == 0 { + return IssueList{}, nil + } + ids := make([]int64, 0, len(issuePins)) + for _, pin := range issuePins { + ids = append(ids, pin.IssueID) + } + + issues := make(IssueList, 0, len(ids)) + if err := db.GetEngine(ctx).In("id", ids).Find(&issues); err != nil { + return nil, err + } + for _, issue := range issues { + for _, pin := range issuePins { + if pin.IssueID == issue.ID { + issue.PinOrder = pin.PinOrder + break + } + } + if (!setting.IsProd || setting.IsInTesting) && issue.PinOrder == 0 { + panic("It should not happen that a pinned Issue has no PinOrder") + } + } + sort.Slice(issues, func(i, j int) bool { + return issues[i].PinOrder < issues[j].PinOrder + }) + + if err = issues.LoadAttributes(ctx); err != nil { + return nil, err + } + + return issues, nil +} + +// IsNewPinAllowed returns if a new Issue or Pull request can be pinned +func IsNewPinAllowed(ctx context.Context, repoID int64, isPull bool) (bool, error) { + var maxPin int + _, err := db.GetEngine(ctx).SQL("SELECT COUNT(pin_order) FROM issue_pin WHERE repo_id = ? AND is_pull = ?", repoID, isPull).Get(&maxPin) + if err != nil { + return false, err + } + + return maxPin < setting.Repository.Issue.MaxPinned, nil +} diff --git a/models/issues/issue_project.go b/models/issues/issue_project.go index f520604321c9d..01852447834c7 100644 --- a/models/issues/issue_project.go +++ b/models/issues/issue_project.go @@ -49,6 +49,21 @@ func (issue *Issue) ProjectColumnID(ctx context.Context) (int64, error) { return ip.ProjectColumnID, nil } +func LoadProjectIssueColumnMap(ctx context.Context, projectID, defaultColumnID int64) (map[int64]int64, error) { + issues := make([]project_model.ProjectIssue, 0) + if err := db.GetEngine(ctx).Where("project_id=?", projectID).Find(&issues); err != nil { + return nil, err + } + result := make(map[int64]int64, len(issues)) + for _, issue := range issues { + if issue.ProjectColumnID == 0 { + issue.ProjectColumnID = defaultColumnID + } + result[issue.IssueID] = issue.ProjectColumnID + } + return result, nil +} + // LoadIssuesFromColumn load issues assigned to this column func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column, opts *IssuesOptions) (IssueList, error) { issueList, err := Issues(ctx, opts.Copy(func(o *IssuesOptions) { @@ -61,11 +76,11 @@ func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column, opts *Is } if b.Default { - issues, err := Issues(ctx, &IssuesOptions{ - ProjectColumnID: db.NoConditionID, - ProjectID: b.ProjectID, - SortType: "project-column-sorting", - }) + issues, err := Issues(ctx, opts.Copy(func(o *IssuesOptions) { + o.ProjectColumnID = db.NoConditionID + o.ProjectID = b.ProjectID + o.SortType = "project-column-sorting" + })) if err != nil { return nil, err } @@ -79,19 +94,6 @@ func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column, opts *Is return issueList, nil } -// LoadIssuesFromColumnList load issues assigned to the columns -func LoadIssuesFromColumnList(ctx context.Context, bs project_model.ColumnList, opts *IssuesOptions) (map[int64]IssueList, error) { - issuesMap := make(map[int64]IssueList, len(bs)) - for i := range bs { - il, err := LoadIssuesFromColumn(ctx, bs[i], opts) - if err != nil { - return nil, err - } - issuesMap[bs[i].ID] = il - } - return issuesMap, nil -} - // IssueAssignOrRemoveProject changes the project associated with an issue // If newProjectID is 0, the issue is removed from the project func IssueAssignOrRemoveProject(ctx context.Context, issue *Issue, doer *user_model.User, newProjectID, newColumnID int64) error { @@ -112,7 +114,7 @@ func IssueAssignOrRemoveProject(ctx context.Context, issue *Issue, doer *user_mo return util.NewPermissionDeniedErrorf("issue %d can't be accessed by project %d", issue.ID, newProject.ID) } if newColumnID == 0 { - newDefaultColumn, err := newProject.GetDefaultColumn(ctx) + newDefaultColumn, err := newProject.MustDefaultColumn(ctx) if err != nil { return err } diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index f1cd125d495c4..694b918755dda 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -49,9 +49,9 @@ type IssuesOptions struct { //nolint // prioritize issues from this repo PriorityRepoID int64 IsArchived optional.Option[bool] - Org *organization.Organization // issues permission scope - Team *organization.Team // issues permission scope - User *user_model.User // issues permission scope + Owner *user_model.User // issues permission scope, it could be an organization or a user + Team *organization.Team // issues permission scope + Doer *user_model.User // issues permission scope } // Copy returns a copy of the options. @@ -273,8 +273,12 @@ func applyConditions(sess *xorm.Session, opts *IssuesOptions) { applyLabelsCondition(sess, opts) - if opts.User != nil { - sess.And(issuePullAccessibleRepoCond("issue.repo_id", opts.User.ID, opts.Org, opts.Team, opts.IsPull.Value())) + if opts.Owner != nil { + sess.And(repo_model.UserOwnedRepoCond(opts.Owner.ID)) + } + + if opts.Doer != nil && !opts.Doer.IsAdmin { + sess.And(issuePullAccessibleRepoCond("issue.repo_id", opts.Doer.ID, opts.Owner, opts.Team, opts.IsPull.Value())) } } @@ -321,20 +325,20 @@ func teamUnitsRepoCond(id string, userID, orgID, teamID int64, units ...unit.Typ } // issuePullAccessibleRepoCond userID must not be zero, this condition require join repository table -func issuePullAccessibleRepoCond(repoIDstr string, userID int64, org *organization.Organization, team *organization.Team, isPull bool) builder.Cond { +func issuePullAccessibleRepoCond(repoIDstr string, userID int64, owner *user_model.User, team *organization.Team, isPull bool) builder.Cond { cond := builder.NewCond() unitType := unit.TypeIssues if isPull { unitType = unit.TypePullRequests } - if org != nil { + if owner != nil && owner.IsOrganization() { if team != nil { - cond = cond.And(teamUnitsRepoCond(repoIDstr, userID, org.ID, team.ID, unitType)) // special team member repos + cond = cond.And(teamUnitsRepoCond(repoIDstr, userID, owner.ID, team.ID, unitType)) // special team member repos } else { cond = cond.And( builder.Or( - repo_model.UserOrgUnitRepoCond(repoIDstr, userID, org.ID, unitType), // team member repos - repo_model.UserOrgPublicUnitRepoCond(userID, org.ID), // user org public non-member repos, TODO: check repo has issues + repo_model.UserOrgUnitRepoCond(repoIDstr, userID, owner.ID, unitType), // team member repos + repo_model.UserOrgPublicUnitRepoCond(userID, owner.ID), // user org public non-member repos, TODO: check repo has issues ), ) } diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 95364ab705751..87d674a440999 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -373,6 +373,7 @@ func prepareMigrationTasks() []*migration { // Gitea 1.23.0-rc0 ends at migration ID number 311 (database version 312) newMigration(312, "Add DeleteBranchAfterMerge to AutoMerge", v1_24.AddDeleteBranchAfterMergeForAutoMerge), + newMigration(313, "Move PinOrder from issue table to a new table issue_pin", v1_24.MovePinOrderToTableIssuePin), } return preparedMigrations } diff --git a/models/migrations/v1_24/v313.go b/models/migrations/v1_24/v313.go new file mode 100644 index 0000000000000..ee9d479340873 --- /dev/null +++ b/models/migrations/v1_24/v313.go @@ -0,0 +1,31 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_24 //nolint + +import ( + "code.gitea.io/gitea/models/migrations/base" + + "xorm.io/xorm" +) + +func MovePinOrderToTableIssuePin(x *xorm.Engine) error { + type IssuePin struct { + ID int64 `xorm:"pk autoincr"` + RepoID int64 `xorm:"UNIQUE(s) NOT NULL"` + IssueID int64 `xorm:"UNIQUE(s) NOT NULL"` + IsPull bool `xorm:"NOT NULL"` + PinOrder int `xorm:"DEFAULT 0"` + } + + if err := x.Sync(new(IssuePin)); err != nil { + return err + } + + if _, err := x.Exec("INSERT INTO issue_pin (repo_id, issue_id, is_pull, pin_order) SELECT repo_id, id, is_pull, pin_order FROM issue WHERE pin_order > 0"); err != nil { + return err + } + sess := x.NewSession() + defer sess.Close() + return base.DropTableColumns(sess, "issue", "pin_order") +} diff --git a/models/project/column.go b/models/project/column.go index 222f44859928e..5f581b58804cb 100644 --- a/models/project/column.go +++ b/models/project/column.go @@ -48,6 +48,8 @@ type Column struct { ProjectID int64 `xorm:"INDEX NOT NULL"` CreatorID int64 `xorm:"NOT NULL"` + NumIssues int64 `xorm:"-"` + CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` } @@ -57,20 +59,6 @@ func (Column) TableName() string { return "project_board" // TODO: the legacy table name should be project_column } -// NumIssues return counter of all issues assigned to the column -func (c *Column) NumIssues(ctx context.Context) int { - total, err := db.GetEngine(ctx).Table("project_issue"). - Where("project_id=?", c.ProjectID). - And("project_board_id=?", c.ID). - GroupBy("issue_id"). - Cols("issue_id"). - Count() - if err != nil { - return 0 - } - return int(total) -} - func (c *Column) GetIssues(ctx context.Context) ([]*ProjectIssue, error) { issues := make([]*ProjectIssue, 0, 5) if err := db.GetEngine(ctx).Where("project_id=?", c.ProjectID). @@ -192,7 +180,7 @@ func deleteColumnByID(ctx context.Context, columnID int64) error { if err != nil { return err } - defaultColumn, err := project.GetDefaultColumn(ctx) + defaultColumn, err := project.MustDefaultColumn(ctx) if err != nil { return err } @@ -257,8 +245,8 @@ func (p *Project) GetColumns(ctx context.Context) (ColumnList, error) { return columns, nil } -// GetDefaultColumn return default column and ensure only one exists -func (p *Project) GetDefaultColumn(ctx context.Context) (*Column, error) { +// getDefaultColumn return default column and ensure only one exists +func (p *Project) getDefaultColumn(ctx context.Context) (*Column, error) { var column Column has, err := db.GetEngine(ctx). Where("project_id=? AND `default` = ?", p.ID, true). @@ -270,6 +258,33 @@ func (p *Project) GetDefaultColumn(ctx context.Context) (*Column, error) { if has { return &column, nil } + return nil, ErrProjectColumnNotExist{ColumnID: 0} +} + +// MustDefaultColumn returns the default column for a project. +// If one exists, it is returned +// If none exists, the first column will be elevated to the default column of this project +func (p *Project) MustDefaultColumn(ctx context.Context) (*Column, error) { + c, err := p.getDefaultColumn(ctx) + if err != nil && !IsErrProjectColumnNotExist(err) { + return nil, err + } + if c != nil { + return c, nil + } + + var column Column + has, err := db.GetEngine(ctx).Where("project_id=?", p.ID).OrderBy("sorting, id").Get(&column) + if err != nil { + return nil, err + } + if has { + column.Default = true + if _, err := db.GetEngine(ctx).ID(column.ID).Cols("`default`").Update(&column); err != nil { + return nil, err + } + return &column, nil + } // create a default column if none is found column = Column{ diff --git a/models/project/column_test.go b/models/project/column_test.go index 566667e45d133..66db23a3e429c 100644 --- a/models/project/column_test.go +++ b/models/project/column_test.go @@ -20,19 +20,19 @@ func TestGetDefaultColumn(t *testing.T) { assert.NoError(t, err) // check if default column was added - column, err := projectWithoutDefault.GetDefaultColumn(db.DefaultContext) + column, err := projectWithoutDefault.MustDefaultColumn(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, int64(5), column.ProjectID) - assert.Equal(t, "Uncategorized", column.Title) + assert.Equal(t, "Done", column.Title) projectWithMultipleDefaults, err := GetProjectByID(db.DefaultContext, 6) assert.NoError(t, err) // check if multiple defaults were removed - column, err = projectWithMultipleDefaults.GetDefaultColumn(db.DefaultContext) + column, err = projectWithMultipleDefaults.MustDefaultColumn(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, int64(6), column.ProjectID) - assert.Equal(t, int64(9), column.ID) + assert.Equal(t, int64(9), column.ID) // there are 2 default columns in the test data, use the latest one // set 8 as default column assert.NoError(t, SetDefaultColumn(db.DefaultContext, column.ProjectID, 8)) diff --git a/models/project/issue.go b/models/project/issue.go index b4347a9c2b4c6..98eed2a2137b5 100644 --- a/models/project/issue.go +++ b/models/project/issue.go @@ -8,7 +8,6 @@ import ( "fmt" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" ) @@ -34,48 +33,6 @@ func deleteProjectIssuesByProjectID(ctx context.Context, projectID int64) error return err } -// NumIssues return counter of all issues assigned to a project -func (p *Project) NumIssues(ctx context.Context) int { - c, err := db.GetEngine(ctx).Table("project_issue"). - Where("project_id=?", p.ID). - GroupBy("issue_id"). - Cols("issue_id"). - Count() - if err != nil { - log.Error("NumIssues: %v", err) - return 0 - } - return int(c) -} - -// NumClosedIssues return counter of closed issues assigned to a project -func (p *Project) NumClosedIssues(ctx context.Context) int { - c, err := db.GetEngine(ctx).Table("project_issue"). - Join("INNER", "issue", "project_issue.issue_id=issue.id"). - Where("project_issue.project_id=? AND issue.is_closed=?", p.ID, true). - Cols("issue_id"). - Count() - if err != nil { - log.Error("NumClosedIssues: %v", err) - return 0 - } - return int(c) -} - -// NumOpenIssues return counter of open issues assigned to a project -func (p *Project) NumOpenIssues(ctx context.Context) int { - c, err := db.GetEngine(ctx).Table("project_issue"). - Join("INNER", "issue", "project_issue.issue_id=issue.id"). - Where("project_issue.project_id=? AND issue.is_closed=?", p.ID, false). - Cols("issue_id"). - Count() - if err != nil { - log.Error("NumOpenIssues: %v", err) - return 0 - } - return int(c) -} - func (c *Column) moveIssuesToAnotherColumn(ctx context.Context, newColumn *Column) error { if c.ProjectID != newColumn.ProjectID { return fmt.Errorf("columns have to be in the same project") diff --git a/models/project/project.go b/models/project/project.go index 20b5df0b6e4de..d27e0530947fa 100644 --- a/models/project/project.go +++ b/models/project/project.go @@ -97,6 +97,9 @@ type Project struct { Type Type RenderedContent template.HTML `xorm:"-"` + NumOpenIssues int64 `xorm:"-"` + NumClosedIssues int64 `xorm:"-"` + NumIssues int64 `xorm:"-"` CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` diff --git a/modules/indexer/issues/db/options.go b/modules/indexer/issues/db/options.go index 42834f6e8863b..87ce398a202d0 100644 --- a/modules/indexer/issues/db/options.go +++ b/modules/indexer/issues/db/options.go @@ -73,9 +73,9 @@ func ToDBOptions(ctx context.Context, options *internal.SearchOptions) (*issue_m UpdatedBeforeUnix: options.UpdatedBeforeUnix.Value(), PriorityRepoID: 0, IsArchived: options.IsArchived, - Org: nil, + Owner: nil, Team: nil, - User: nil, + Doer: nil, } if len(options.MilestoneIDs) == 1 && options.MilestoneIDs[0] == 0 { diff --git a/modules/util/error.go b/modules/util/error.go index 07fadf3cab7f9..13b592a9f8cf1 100644 --- a/modules/util/error.go +++ b/modules/util/error.go @@ -10,13 +10,16 @@ import ( // Common Errors forming the base of our error system // -// Many Errors returned by Gitea can be tested against these errors -// using errors.Is. +// Many Errors returned by Gitea can be tested against these errors using "errors.Is". var ( - ErrInvalidArgument = errors.New("invalid argument") - ErrPermissionDenied = errors.New("permission denied") - ErrAlreadyExist = errors.New("resource already exists") - ErrNotExist = errors.New("resource does not exist") + ErrInvalidArgument = errors.New("invalid argument") // also implies HTTP 400 + ErrPermissionDenied = errors.New("permission denied") // also implies HTTP 403 + ErrNotExist = errors.New("resource does not exist") // also implies HTTP 404 + ErrAlreadyExist = errors.New("resource already exists") // also implies HTTP 409 + + // ErrUnprocessableContent implies HTTP 422, syntax of the request content was correct, + // but server was unable to process the contained instructions + ErrUnprocessableContent = errors.New("unprocessable content") ) // SilentWrap provides a simple wrapper for a wrapped error where the wrapped error message plays no part in the error message diff --git a/routers/api/actions/artifacts.go b/routers/api/actions/artifacts.go index 910edd6d5895d..0832e52f5558b 100644 --- a/routers/api/actions/artifacts.go +++ b/routers/api/actions/artifacts.go @@ -135,7 +135,7 @@ func ArtifactContexter() func(next http.Handler) http.Handler { // we should verify the ACTIONS_RUNTIME_TOKEN authHeader := req.Header.Get("Authorization") if len(authHeader) == 0 || !strings.HasPrefix(authHeader, "Bearer ") { - ctx.Error(http.StatusUnauthorized, "Bad authorization header") + ctx.HTTPError(http.StatusUnauthorized, "Bad authorization header") return } @@ -147,12 +147,12 @@ func ArtifactContexter() func(next http.Handler) http.Handler { task, err = actions.GetTaskByID(req.Context(), tID) if err != nil { log.Error("Error runner api getting task by ID: %v", err) - ctx.Error(http.StatusInternalServerError, "Error runner api getting task by ID") + ctx.HTTPError(http.StatusInternalServerError, "Error runner api getting task by ID") return } if task.Status != actions.StatusRunning { log.Error("Error runner api getting task: task is not running") - ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running") + ctx.HTTPError(http.StatusInternalServerError, "Error runner api getting task: task is not running") return } } else { @@ -162,14 +162,14 @@ func ArtifactContexter() func(next http.Handler) http.Handler { task, err = actions.GetRunningTaskByToken(req.Context(), authToken) if err != nil { log.Error("Error runner api getting task: %v", err) - ctx.Error(http.StatusInternalServerError, "Error runner api getting task") + ctx.HTTPError(http.StatusInternalServerError, "Error runner api getting task") return } } if err := task.LoadJob(req.Context()); err != nil { log.Error("Error runner api getting job: %v", err) - ctx.Error(http.StatusInternalServerError, "Error runner api getting job") + ctx.HTTPError(http.StatusInternalServerError, "Error runner api getting job") return } @@ -211,7 +211,7 @@ func (ar artifactRoutes) getUploadArtifactURL(ctx *ArtifactContext) { var req getUploadArtifactRequest if err := json.NewDecoder(ctx.Req.Body).Decode(&req); err != nil { log.Error("Error decode request body: %v", err) - ctx.Error(http.StatusInternalServerError, "Error decode request body") + ctx.HTTPError(http.StatusInternalServerError, "Error decode request body") return } @@ -250,7 +250,7 @@ func (ar artifactRoutes) uploadArtifact(ctx *ArtifactContext) { expiredDays, err = strconv.ParseInt(queryRetentionDays, 10, 64) if err != nil { log.Error("Error parse retention days: %v", err) - ctx.Error(http.StatusBadRequest, "Error parse retention days") + ctx.HTTPError(http.StatusBadRequest, "Error parse retention days") return } } @@ -261,7 +261,7 @@ func (ar artifactRoutes) uploadArtifact(ctx *ArtifactContext) { artifact, err := actions.CreateArtifact(ctx, task, artifactName, artifactPath, expiredDays) if err != nil { log.Error("Error create or get artifact: %v", err) - ctx.Error(http.StatusInternalServerError, "Error create or get artifact") + ctx.HTTPError(http.StatusInternalServerError, "Error create or get artifact") return } @@ -271,7 +271,7 @@ func (ar artifactRoutes) uploadArtifact(ctx *ArtifactContext) { chunksTotalSize, err := saveUploadChunk(ar.fs, ctx, artifact, contentLength, runID) if err != nil { log.Error("Error save upload chunk: %v", err) - ctx.Error(http.StatusInternalServerError, "Error save upload chunk") + ctx.HTTPError(http.StatusInternalServerError, "Error save upload chunk") return } @@ -285,7 +285,7 @@ func (ar artifactRoutes) uploadArtifact(ctx *ArtifactContext) { artifact.ContentEncoding = ctx.Req.Header.Get("Content-Encoding") if err := actions.UpdateArtifactByID(ctx, artifact.ID, artifact); err != nil { log.Error("Error update artifact: %v", err) - ctx.Error(http.StatusInternalServerError, "Error update artifact") + ctx.HTTPError(http.StatusInternalServerError, "Error update artifact") return } log.Debug("[artifact] update artifact size, artifact_id: %d, size: %d, compressed size: %d", @@ -307,12 +307,12 @@ func (ar artifactRoutes) comfirmUploadArtifact(ctx *ArtifactContext) { artifactName := ctx.Req.URL.Query().Get("artifactName") if artifactName == "" { log.Error("Error artifact name is empty") - ctx.Error(http.StatusBadRequest, "Error artifact name is empty") + ctx.HTTPError(http.StatusBadRequest, "Error artifact name is empty") return } if err := mergeChunksForRun(ctx, ar.fs, runID, artifactName); err != nil { log.Error("Error merge chunks: %v", err) - ctx.Error(http.StatusInternalServerError, "Error merge chunks") + ctx.HTTPError(http.StatusInternalServerError, "Error merge chunks") return } ctx.JSON(http.StatusOK, map[string]string{ @@ -340,12 +340,12 @@ func (ar artifactRoutes) listArtifacts(ctx *ArtifactContext) { artifacts, err := db.Find[actions.ActionArtifact](ctx, actions.FindArtifactsOptions{RunID: runID}) if err != nil { log.Error("Error getting artifacts: %v", err) - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } if len(artifacts) == 0 { log.Debug("[artifact] handleListArtifacts, no artifacts") - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -405,18 +405,18 @@ func (ar artifactRoutes) getDownloadArtifactURL(ctx *ArtifactContext) { }) if err != nil { log.Error("Error getting artifacts: %v", err) - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } if len(artifacts) == 0 { log.Debug("[artifact] getDownloadArtifactURL, no artifacts") - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if itemPath != artifacts[0].ArtifactName { log.Error("Error dismatch artifact name, itemPath: %v, artifact: %v", itemPath, artifacts[0].ArtifactName) - ctx.Error(http.StatusBadRequest, "Error dismatch artifact name") + ctx.HTTPError(http.StatusBadRequest, "Error dismatch artifact name") return } @@ -460,24 +460,24 @@ func (ar artifactRoutes) downloadArtifact(ctx *ArtifactContext) { artifact, exist, err := db.GetByID[actions.ActionArtifact](ctx, artifactID) if err != nil { log.Error("Error getting artifact: %v", err) - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } if !exist { log.Error("artifact with ID %d does not exist", artifactID) - ctx.Error(http.StatusNotFound, fmt.Sprintf("artifact with ID %d does not exist", artifactID)) + ctx.HTTPError(http.StatusNotFound, fmt.Sprintf("artifact with ID %d does not exist", artifactID)) return } if artifact.RunID != runID { log.Error("Error mismatch runID and artifactID, task: %v, artifact: %v", runID, artifactID) - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } fd, err := ar.fs.Open(artifact.StoragePath) if err != nil { log.Error("Error opening file: %v", err) - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } defer fd.Close() diff --git a/routers/api/actions/artifacts_utils.go b/routers/api/actions/artifacts_utils.go index a4ca5797dc661..77ce765098636 100644 --- a/routers/api/actions/artifacts_utils.go +++ b/routers/api/actions/artifacts_utils.go @@ -26,7 +26,7 @@ var invalidArtifactNameChars = strings.Join([]string{"\\", "/", "\"", ":", "<", func validateArtifactName(ctx *ArtifactContext, artifactName string) bool { if strings.ContainsAny(artifactName, invalidArtifactNameChars) { log.Error("Error checking artifact name contains invalid character") - ctx.Error(http.StatusBadRequest, "Error checking artifact name contains invalid character") + ctx.HTTPError(http.StatusBadRequest, "Error checking artifact name contains invalid character") return false } return true @@ -37,7 +37,7 @@ func validateRunID(ctx *ArtifactContext) (*actions.ActionTask, int64, bool) { runID := ctx.PathParamInt64("run_id") if task.Job.RunID != runID { log.Error("Error runID not match") - ctx.Error(http.StatusBadRequest, "run-id does not match") + ctx.HTTPError(http.StatusBadRequest, "run-id does not match") return nil, 0, false } return task, runID, true @@ -48,7 +48,7 @@ func validateRunIDV4(ctx *ArtifactContext, rawRunID string) (*actions.ActionTask runID, err := strconv.ParseInt(rawRunID, 10, 64) if err != nil || task.Job.RunID != runID { log.Error("Error runID not match") - ctx.Error(http.StatusBadRequest, "run-id does not match") + ctx.HTTPError(http.StatusBadRequest, "run-id does not match") return nil, 0, false } return task, runID, true @@ -62,7 +62,7 @@ func validateArtifactHash(ctx *ArtifactContext, artifactName string) bool { return true } log.Error("Invalid artifact hash: %s", paramHash) - ctx.Error(http.StatusBadRequest, "Invalid artifact hash") + ctx.HTTPError(http.StatusBadRequest, "Invalid artifact hash") return false } diff --git a/routers/api/actions/artifactsv4.go b/routers/api/actions/artifactsv4.go index d29754b6e989c..665156d936c57 100644 --- a/routers/api/actions/artifactsv4.go +++ b/routers/api/actions/artifactsv4.go @@ -187,29 +187,29 @@ func (r artifactV4Routes) verifySignature(ctx *ArtifactContext, endp string) (*a expecedsig := r.buildSignature(endp, expires, artifactName, taskID, artifactID) if !hmac.Equal(dsig, expecedsig) { log.Error("Error unauthorized") - ctx.Error(http.StatusUnauthorized, "Error unauthorized") + ctx.HTTPError(http.StatusUnauthorized, "Error unauthorized") return nil, "", false } t, err := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", expires) if err != nil || t.Before(time.Now()) { log.Error("Error link expired") - ctx.Error(http.StatusUnauthorized, "Error link expired") + ctx.HTTPError(http.StatusUnauthorized, "Error link expired") return nil, "", false } task, err := actions.GetTaskByID(ctx, taskID) if err != nil { log.Error("Error runner api getting task by ID: %v", err) - ctx.Error(http.StatusInternalServerError, "Error runner api getting task by ID") + ctx.HTTPError(http.StatusInternalServerError, "Error runner api getting task by ID") return nil, "", false } if task.Status != actions.StatusRunning { log.Error("Error runner api getting task: task is not running") - ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running") + ctx.HTTPError(http.StatusInternalServerError, "Error runner api getting task: task is not running") return nil, "", false } if err := task.LoadJob(ctx); err != nil { log.Error("Error runner api getting job: %v", err) - ctx.Error(http.StatusInternalServerError, "Error runner api getting job") + ctx.HTTPError(http.StatusInternalServerError, "Error runner api getting job") return nil, "", false } return task, artifactName, true @@ -230,13 +230,13 @@ func (r *artifactV4Routes) parseProtbufBody(ctx *ArtifactContext, req protorefle body, err := io.ReadAll(ctx.Req.Body) if err != nil { log.Error("Error decode request body: %v", err) - ctx.Error(http.StatusInternalServerError, "Error decode request body") + ctx.HTTPError(http.StatusInternalServerError, "Error decode request body") return false } err = protojson.Unmarshal(body, req) if err != nil { log.Error("Error decode request body: %v", err) - ctx.Error(http.StatusInternalServerError, "Error decode request body") + ctx.HTTPError(http.StatusInternalServerError, "Error decode request body") return false } return true @@ -246,7 +246,7 @@ func (r *artifactV4Routes) sendProtbufBody(ctx *ArtifactContext, req protoreflec resp, err := protojson.Marshal(req) if err != nil { log.Error("Error encode response body: %v", err) - ctx.Error(http.StatusInternalServerError, "Error encode response body") + ctx.HTTPError(http.StatusInternalServerError, "Error encode response body") return } ctx.Resp.Header().Set("Content-Type", "application/json;charset=utf-8") @@ -275,7 +275,7 @@ func (r *artifactV4Routes) createArtifact(ctx *ArtifactContext) { artifact, err := actions.CreateArtifact(ctx, ctx.ActionTask, artifactName, artifactName+".zip", rententionDays) if err != nil { log.Error("Error create or get artifact: %v", err) - ctx.Error(http.StatusInternalServerError, "Error create or get artifact") + ctx.HTTPError(http.StatusInternalServerError, "Error create or get artifact") return } artifact.ContentEncoding = ArtifactV4ContentEncoding @@ -283,7 +283,7 @@ func (r *artifactV4Routes) createArtifact(ctx *ArtifactContext) { artifact.FileCompressedSize = 0 if err := actions.UpdateArtifactByID(ctx, artifact.ID, artifact); err != nil { log.Error("Error UpdateArtifactByID: %v", err) - ctx.Error(http.StatusInternalServerError, "Error UpdateArtifactByID") + ctx.HTTPError(http.StatusInternalServerError, "Error UpdateArtifactByID") return } @@ -309,28 +309,28 @@ func (r *artifactV4Routes) uploadArtifact(ctx *ArtifactContext) { artifact, err := r.getArtifactByName(ctx, task.Job.RunID, artifactName) if err != nil { log.Error("Error artifact not found: %v", err) - ctx.Error(http.StatusNotFound, "Error artifact not found") + ctx.HTTPError(http.StatusNotFound, "Error artifact not found") return } _, err = appendUploadChunk(r.fs, ctx, artifact, artifact.FileSize, ctx.Req.ContentLength, artifact.RunID) if err != nil { log.Error("Error runner api getting task: task is not running") - ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running") + ctx.HTTPError(http.StatusInternalServerError, "Error runner api getting task: task is not running") return } artifact.FileCompressedSize += ctx.Req.ContentLength artifact.FileSize += ctx.Req.ContentLength if err := actions.UpdateArtifactByID(ctx, artifact.ID, artifact); err != nil { log.Error("Error UpdateArtifactByID: %v", err) - ctx.Error(http.StatusInternalServerError, "Error UpdateArtifactByID") + ctx.HTTPError(http.StatusInternalServerError, "Error UpdateArtifactByID") return } } else { _, err := r.fs.Save(fmt.Sprintf("tmpv4%d/block-%d-%d-%s", task.Job.RunID, task.Job.RunID, ctx.Req.ContentLength, base64.URLEncoding.EncodeToString([]byte(blockid))), ctx.Req.Body, -1) if err != nil { log.Error("Error runner api getting task: task is not running") - ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running") + ctx.HTTPError(http.StatusInternalServerError, "Error runner api getting task: task is not running") return } } @@ -341,7 +341,7 @@ func (r *artifactV4Routes) uploadArtifact(ctx *ArtifactContext) { _, err := r.fs.Save(fmt.Sprintf("tmpv4%d/%d-%d-blocklist", task.Job.RunID, task.Job.RunID, artifactID), ctx.Req.Body, -1) if err != nil { log.Error("Error runner api getting task: task is not running") - ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running") + ctx.HTTPError(http.StatusInternalServerError, "Error runner api getting task: task is not running") return } ctx.JSON(http.StatusCreated, "created") @@ -389,7 +389,7 @@ func (r *artifactV4Routes) finalizeArtifact(ctx *ArtifactContext) { artifact, err := r.getArtifactByName(ctx, runID, req.Name) if err != nil { log.Error("Error artifact not found: %v", err) - ctx.Error(http.StatusNotFound, "Error artifact not found") + ctx.HTTPError(http.StatusNotFound, "Error artifact not found") return } @@ -400,20 +400,20 @@ func (r *artifactV4Routes) finalizeArtifact(ctx *ArtifactContext) { chunkMap, err := listChunksByRunID(r.fs, runID) if err != nil { log.Error("Error merge chunks: %v", err) - ctx.Error(http.StatusInternalServerError, "Error merge chunks") + ctx.HTTPError(http.StatusInternalServerError, "Error merge chunks") return } chunks, ok = chunkMap[artifact.ID] if !ok { log.Error("Error merge chunks") - ctx.Error(http.StatusInternalServerError, "Error merge chunks") + ctx.HTTPError(http.StatusInternalServerError, "Error merge chunks") return } } else { chunks, err = listChunksByRunIDV4(r.fs, runID, artifact.ID, blockList) if err != nil { log.Error("Error merge chunks: %v", err) - ctx.Error(http.StatusInternalServerError, "Error merge chunks") + ctx.HTTPError(http.StatusInternalServerError, "Error merge chunks") return } artifact.FileSize = chunks[len(chunks)-1].End + 1 @@ -426,7 +426,7 @@ func (r *artifactV4Routes) finalizeArtifact(ctx *ArtifactContext) { } if err := mergeChunksForArtifact(ctx, chunks, r.fs, artifact, checksum); err != nil { log.Error("Error merge chunks: %v", err) - ctx.Error(http.StatusInternalServerError, "Error merge chunks") + ctx.HTTPError(http.StatusInternalServerError, "Error merge chunks") return } @@ -451,12 +451,12 @@ func (r *artifactV4Routes) listArtifacts(ctx *ArtifactContext) { artifacts, err := db.Find[actions.ActionArtifact](ctx, actions.FindArtifactsOptions{RunID: runID}) if err != nil { log.Error("Error getting artifacts: %v", err) - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } if len(artifacts) == 0 { log.Debug("[artifact] handleListArtifacts, no artifacts") - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -507,7 +507,7 @@ func (r *artifactV4Routes) getSignedArtifactURL(ctx *ArtifactContext) { artifact, err := r.getArtifactByName(ctx, runID, artifactName) if err != nil { log.Error("Error artifact not found: %v", err) - ctx.Error(http.StatusNotFound, "Error artifact not found") + ctx.HTTPError(http.StatusNotFound, "Error artifact not found") return } @@ -535,7 +535,7 @@ func (r *artifactV4Routes) downloadArtifact(ctx *ArtifactContext) { artifact, err := r.getArtifactByName(ctx, task.Job.RunID, artifactName) if err != nil { log.Error("Error artifact not found: %v", err) - ctx.Error(http.StatusNotFound, "Error artifact not found") + ctx.HTTPError(http.StatusNotFound, "Error artifact not found") return } @@ -559,14 +559,14 @@ func (r *artifactV4Routes) deleteArtifact(ctx *ArtifactContext) { artifact, err := r.getArtifactByName(ctx, runID, req.Name) if err != nil { log.Error("Error artifact not found: %v", err) - ctx.Error(http.StatusNotFound, "Error artifact not found") + ctx.HTTPError(http.StatusNotFound, "Error artifact not found") return } err = actions.SetArtifactNeedDelete(ctx, runID, req.Name) if err != nil { log.Error("Error deleting artifacts: %v", err) - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index 41c3eb95e9011..b64306037f76a 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -49,32 +49,32 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) { if accessMode == perm.AccessModeRead { scopeMatched, err = scope.HasScope(auth_model.AccessTokenScopeReadPackage) if err != nil { - ctx.Error(http.StatusInternalServerError, "HasScope", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "HasScope", err.Error()) return } } else if accessMode == perm.AccessModeWrite { scopeMatched, err = scope.HasScope(auth_model.AccessTokenScopeWritePackage) if err != nil { - ctx.Error(http.StatusInternalServerError, "HasScope", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "HasScope", err.Error()) return } } if !scopeMatched { ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea Package API"`) - ctx.Error(http.StatusUnauthorized, "reqPackageAccess", "user should have specific permission or be a site admin") + ctx.HTTPError(http.StatusUnauthorized, "reqPackageAccess", "user should have specific permission or be a site admin") return } // check if scope only applies to public resources publicOnly, err := scope.PublicOnly() if err != nil { - ctx.Error(http.StatusForbidden, "tokenRequiresScope", "parsing public resource scope failed: "+err.Error()) + ctx.HTTPError(http.StatusForbidden, "tokenRequiresScope", "parsing public resource scope failed: "+err.Error()) return } if publicOnly { if ctx.Package != nil && ctx.Package.Owner.Visibility.IsPrivate() { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public packages") + ctx.HTTPError(http.StatusForbidden, "reqToken", "token scope is limited to public packages") return } } @@ -83,7 +83,7 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) { if ctx.Package.AccessMode < accessMode && !ctx.IsUserSiteAdmin() { ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea Package API"`) - ctx.Error(http.StatusUnauthorized, "reqPackageAccess", "user should have specific permission or be a site admin") + ctx.HTTPError(http.StatusUnauthorized, "reqPackageAccess", "user should have specific permission or be a site admin") return } } @@ -100,7 +100,7 @@ func verifyAuth(r *web.Router, authMethods []auth.Method) { ctx.Doer, err = authGroup.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session) if err != nil { log.Error("Failed to verify user: %v", err) - ctx.Error(http.StatusUnauthorized, "authGroup.Verify") + ctx.HTTPError(http.StatusUnauthorized, "authGroup.Verify") return } ctx.IsSigned = ctx.Doer != nil diff --git a/routers/api/v1/activitypub/person.go b/routers/api/v1/activitypub/person.go index 995a148f0bdb1..0b0db011c6a80 100644 --- a/routers/api/v1/activitypub/person.go +++ b/routers/api/v1/activitypub/person.go @@ -41,14 +41,14 @@ func Person(ctx *context.APIContext) { person.Name = ap.NaturalLanguageValuesNew() err := person.Name.Set("en", ap.Content(ctx.ContextUser.FullName)) if err != nil { - ctx.ServerError("Set Name", err) + ctx.APIErrorInternal(err) return } person.PreferredUsername = ap.NaturalLanguageValuesNew() err = person.PreferredUsername.Set("en", ap.Content(ctx.ContextUser.Name)) if err != nil { - ctx.ServerError("Set PreferredUsername", err) + ctx.APIErrorInternal(err) return } @@ -68,14 +68,14 @@ func Person(ctx *context.APIContext) { publicKeyPem, err := activitypub.GetPublicKey(ctx, ctx.ContextUser) if err != nil { - ctx.ServerError("GetPublicKey", err) + ctx.APIErrorInternal(err) return } person.PublicKey.PublicKeyPem = publicKeyPem binary, err := jsonld.WithContext(jsonld.IRI(ap.ActivityBaseURI), jsonld.IRI(ap.SecurityContextURI)).Marshal(person) if err != nil { - ctx.ServerError("MarshalJSON", err) + ctx.APIErrorInternal(err) return } ctx.Resp.Header().Add("Content-Type", activitypub.ActivityStreamsContentType) diff --git a/routers/api/v1/activitypub/reqsignature.go b/routers/api/v1/activitypub/reqsignature.go index 853c3c0b590c1..957d593d89b22 100644 --- a/routers/api/v1/activitypub/reqsignature.go +++ b/routers/api/v1/activitypub/reqsignature.go @@ -89,9 +89,9 @@ func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, er func ReqHTTPSignature() func(ctx *gitea_context.APIContext) { return func(ctx *gitea_context.APIContext) { if authenticated, err := verifyHTTPSignatures(ctx); err != nil { - ctx.ServerError("verifyHttpSignatures", err) + ctx.APIErrorInternal(err) } else if !authenticated { - ctx.Error(http.StatusForbidden, "reqSignature", "request signature verification failed") + ctx.APIError(http.StatusForbidden, "request signature verification failed") } } } diff --git a/routers/api/v1/admin/adopt.go b/routers/api/v1/admin/adopt.go index 55ea8c6758cf6..c2efed7490c25 100644 --- a/routers/api/v1/admin/adopt.go +++ b/routers/api/v1/admin/adopt.go @@ -46,7 +46,7 @@ func ListUnadoptedRepositories(ctx *context.APIContext) { } repoNames, count, err := repo_service.ListUnadoptedRepositories(ctx, ctx.FormString("query"), &listOptions) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -86,33 +86,33 @@ func AdoptRepository(ctx *context.APIContext) { ctxUser, err := user_model.GetUserByName(ctx, ownerName) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return } - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } // check not a repo has, err := repo_model.IsRepositoryModelExist(ctx, ctxUser, repoName) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } isDir, err := util.IsDir(repo_model.RepoPath(ctxUser.Name, repoName)) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if has || !isDir { - ctx.NotFound() + ctx.APIErrorNotFound() return } if _, err := repo_service.AdoptRepository(ctx, ctx.Doer, ctxUser, repo_service.CreateRepoOptions{ Name: repoName, IsPrivate: true, }); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -148,31 +148,31 @@ func DeleteUnadoptedRepository(ctx *context.APIContext) { ctxUser, err := user_model.GetUserByName(ctx, ownerName) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return } - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } // check not a repo has, err := repo_model.IsRepositoryModelExist(ctx, ctxUser, repoName) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } isDir, err := util.IsDir(repo_model.RepoPath(ctxUser.Name, repoName)) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if has || !isDir { - ctx.NotFound() + ctx.APIErrorNotFound() return } if err := repo_service.DeleteUnadoptedRepository(ctx, ctx.Doer, ctxUser, repoName); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/admin/cron.go b/routers/api/v1/admin/cron.go index 962e0077763ff..b4dae11095851 100644 --- a/routers/api/v1/admin/cron.go +++ b/routers/api/v1/admin/cron.go @@ -76,7 +76,7 @@ func PostCronTask(ctx *context.APIContext) { // "$ref": "#/responses/notFound" task := cron.GetTask(ctx.PathParam("task")) if task == nil { - ctx.NotFound() + ctx.APIErrorNotFound() return } task.Run() diff --git a/routers/api/v1/admin/email.go b/routers/api/v1/admin/email.go index 3de94d6868e60..ad078347a4021 100644 --- a/routers/api/v1/admin/email.go +++ b/routers/api/v1/admin/email.go @@ -42,7 +42,7 @@ func GetAllEmails(ctx *context.APIContext) { ListOptions: listOptions, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetAllEmails", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/admin/hooks.go b/routers/api/v1/admin/hooks.go index c812ca182d502..fb1ea4eab6b8f 100644 --- a/routers/api/v1/admin/hooks.go +++ b/routers/api/v1/admin/hooks.go @@ -59,14 +59,14 @@ func ListHooks(ctx *context.APIContext) { sysHooks, err := webhook.GetSystemOrDefaultWebhooks(ctx, isSystemWebhook) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetSystemWebhooks", err) + ctx.APIErrorInternal(err) return } hooks := make([]*api.Hook, len(sysHooks)) for i, hook := range sysHooks { h, err := webhook_service.ToHook(setting.AppURL+"/-/admin", hook) if err != nil { - ctx.Error(http.StatusInternalServerError, "convert.ToHook", err) + ctx.APIErrorInternal(err) return } hooks[i] = h @@ -96,15 +96,15 @@ func GetHook(ctx *context.APIContext) { hook, err := webhook.GetSystemOrDefaultWebhook(ctx, hookID) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetSystemOrDefaultWebhook", err) + ctx.APIErrorInternal(err) } return } h, err := webhook_service.ToHook("/-/admin/", hook) if err != nil { - ctx.Error(http.StatusInternalServerError, "convert.ToHook", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, h) @@ -186,9 +186,9 @@ func DeleteHook(ctx *context.APIContext) { hookID := ctx.PathParamInt64("id") if err := webhook.DeleteDefaultSystemWebhook(ctx, hookID); err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "DeleteDefaultSystemWebhook", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go index a5c299bbf01c8..8808a1587d55f 100644 --- a/routers/api/v1/admin/org.go +++ b/routers/api/v1/admin/org.go @@ -67,9 +67,9 @@ func CreateOrg(ctx *context.APIContext) { db.IsErrNameReserved(err) || db.IsErrNameCharsNotAllowed(err) || db.IsErrNamePatternNotAllowed(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateOrganization", err) + ctx.APIErrorInternal(err) } return } @@ -109,7 +109,7 @@ func GetAllOrgs(ctx *context.APIContext) { Visible: []api.VisibleType{api.VisibleTypePublic, api.VisibleTypeLimited, api.VisibleTypePrivate}, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchOrganizations", err) + ctx.APIErrorInternal(err) return } orgs := make([]*api.Organization, len(users)) diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 53eee72631f37..c4bb85de558ba 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -40,9 +40,9 @@ 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.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "auth.GetSourceByID", err) + ctx.APIErrorInternal(err) } return } @@ -98,13 +98,13 @@ func CreateUser(ctx *context.APIContext) { if u.LoginType == auth.Plain { if len(form.Password) < setting.MinPasswordLength { err := errors.New("PasswordIsRequired") - ctx.Error(http.StatusBadRequest, "PasswordIsRequired", err) + ctx.APIError(http.StatusBadRequest, err) return } if !password.IsComplexEnough(form.Password) { err := errors.New("PasswordComplexity") - ctx.Error(http.StatusBadRequest, "PasswordComplexity", err) + ctx.APIError(http.StatusBadRequest, err) return } @@ -112,7 +112,7 @@ func CreateUser(ctx *context.APIContext) { if password.IsErrIsPwnedRequest(err) { log.Error(err.Error()) } - ctx.Error(http.StatusBadRequest, "PasswordPwned", errors.New("PasswordPwned")) + ctx.APIError(http.StatusBadRequest, errors.New("PasswordPwned")) return } } @@ -143,9 +143,9 @@ func CreateUser(ctx *context.APIContext) { user_model.IsErrEmailCharIsNotSupported(err) || user_model.IsErrEmailInvalid(err) || db.IsErrNamePatternNotAllowed(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateUser", err) + ctx.APIErrorInternal(err) } return } @@ -204,13 +204,13 @@ func EditUser(ctx *context.APIContext) { if err := user_service.UpdateAuth(ctx, ctx.ContextUser, authOpts); err != nil { switch { case errors.Is(err, password.ErrMinLength): - ctx.Error(http.StatusBadRequest, "PasswordTooShort", fmt.Errorf("password must be at least %d characters", setting.MinPasswordLength)) + ctx.APIError(http.StatusBadRequest, fmt.Errorf("password must be at least %d characters", setting.MinPasswordLength)) case errors.Is(err, password.ErrComplexity): - ctx.Error(http.StatusBadRequest, "PasswordComplexity", err) + ctx.APIError(http.StatusBadRequest, err) case errors.Is(err, password.ErrIsPwned), password.IsErrIsPwnedRequest(err): - ctx.Error(http.StatusBadRequest, "PasswordIsPwned", err) + ctx.APIError(http.StatusBadRequest, err) default: - ctx.Error(http.StatusInternalServerError, "UpdateAuth", err) + ctx.APIErrorInternal(err) } return } @@ -219,11 +219,11 @@ func EditUser(ctx *context.APIContext) { if err := user_service.AdminAddOrSetPrimaryEmailAddress(ctx, ctx.ContextUser, *form.Email); err != nil { switch { case user_model.IsErrEmailCharIsNotSupported(err), user_model.IsErrEmailInvalid(err): - ctx.Error(http.StatusBadRequest, "EmailInvalid", err) + ctx.APIError(http.StatusBadRequest, err) case user_model.IsErrEmailAlreadyUsed(err): - ctx.Error(http.StatusBadRequest, "EmailUsed", err) + ctx.APIError(http.StatusBadRequest, err) default: - ctx.Error(http.StatusInternalServerError, "AddOrSetPrimaryEmailAddress", err) + ctx.APIErrorInternal(err) } return } @@ -250,9 +250,9 @@ func EditUser(ctx *context.APIContext) { if err := user_service.UpdateUser(ctx, ctx.ContextUser, opts); err != nil { if user_model.IsErrDeleteLastAdminUser(err) { - ctx.Error(http.StatusBadRequest, "LastAdmin", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "UpdateUser", err) + ctx.APIErrorInternal(err) } return } @@ -290,13 +290,13 @@ func DeleteUser(ctx *context.APIContext) { // "$ref": "#/responses/validationError" if ctx.ContextUser.IsOrganization() { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name)) return } // admin should not delete themself if ctx.ContextUser.ID == ctx.Doer.ID { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("you cannot delete yourself")) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("you cannot delete yourself")) return } @@ -305,9 +305,9 @@ func DeleteUser(ctx *context.APIContext) { org_model.IsErrUserHasOrgs(err) || packages_model.IsErrUserOwnPackages(err) || user_model.IsErrDeleteLastAdminUser(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "DeleteUser", err) + ctx.APIErrorInternal(err) } return } @@ -377,11 +377,11 @@ func DeleteUserPublicKey(ctx *context.APIContext) { if err := asymkey_service.DeletePublicKey(ctx, ctx.ContextUser, ctx.PathParamInt64("id")); err != nil { if asymkey_model.IsErrKeyNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else if asymkey_model.IsErrKeyAccessDenied(err) { - ctx.Error(http.StatusForbidden, "", "You do not have access to this key") + ctx.APIError(http.StatusForbidden, "You do not have access to this key") } else { - ctx.Error(http.StatusInternalServerError, "DeleteUserPublicKey", err) + ctx.APIErrorInternal(err) } return } @@ -432,7 +432,7 @@ func SearchUsers(ctx *context.APIContext) { ListOptions: listOptions, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchUsers", err) + ctx.APIErrorInternal(err) return } @@ -473,7 +473,7 @@ func RenameUser(ctx *context.APIContext) { // "$ref": "#/responses/validationError" if ctx.ContextUser.IsOrganization() { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name)) return } @@ -482,9 +482,9 @@ func RenameUser(ctx *context.APIContext) { // Check if username has been changed if err := user_service.RenameUser(ctx, ctx.ContextUser, newName); err != nil { if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.ServerError("ChangeUserName", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/admin/user_badge.go b/routers/api/v1/admin/user_badge.go index 99e20877fdcb2..6d9665a72bfc8 100644 --- a/routers/api/v1/admin/user_badge.go +++ b/routers/api/v1/admin/user_badge.go @@ -33,7 +33,7 @@ func ListUserBadges(ctx *context.APIContext) { badges, maxResults, err := user_model.GetUserBadges(ctx, ctx.ContextUser) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserBadges", err) + ctx.APIErrorInternal(err) return } @@ -70,7 +70,7 @@ func AddUserBadges(ctx *context.APIContext) { badges := prepareBadgesForReplaceOrAdd(*form) if err := user_model.AddUserBadges(ctx, ctx.ContextUser, badges); err != nil { - ctx.Error(http.StatusInternalServerError, "ReplaceUserBadges", err) + ctx.APIErrorInternal(err) return } @@ -106,7 +106,7 @@ func DeleteUserBadges(ctx *context.APIContext) { badges := prepareBadgesForReplaceOrAdd(*form) if err := user_model.RemoveUserBadges(ctx, ctx.ContextUser, badges); err != nil { - ctx.Error(http.StatusInternalServerError, "ReplaceUserBadges", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 342e1e66bcd5a..907a2f08fe280 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -66,6 +66,7 @@ package v1 import ( + "errors" "fmt" "net/http" "strings" @@ -116,9 +117,9 @@ func sudo() func(ctx *context.APIContext) { user, err := user_model.GetUserByName(ctx, sudo) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return } @@ -154,12 +155,12 @@ func repoAssignment() func(ctx *context.APIContext) { if redirectUserID, err := user_model.LookupUserRedirect(ctx, userName); err == nil { context.RedirectToUser(ctx.Base, userName, redirectUserID) } else if user_model.IsErrUserRedirectNotExist(err) { - ctx.NotFound("GetUserByName", err) + ctx.APIErrorNotFound("GetUserByName", err) } else { - ctx.Error(http.StatusInternalServerError, "LookupUserRedirect", err) + ctx.APIErrorInternal(err) } } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return } @@ -175,12 +176,12 @@ func repoAssignment() func(ctx *context.APIContext) { if err == nil { context.RedirectToRepo(ctx.Base, redirectRepoID) } else if repo_model.IsErrRedirectNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "LookupRepoRedirect", err) + ctx.APIErrorInternal(err) } } else { - ctx.Error(http.StatusInternalServerError, "GetRepositoryByName", err) + ctx.APIErrorInternal(err) } return } @@ -192,11 +193,11 @@ func repoAssignment() func(ctx *context.APIContext) { taskID := ctx.Data["ActionsTaskID"].(int64) task, err := actions_model.GetTaskByID(ctx, taskID) if err != nil { - ctx.Error(http.StatusInternalServerError, "actions_model.GetTaskByID", err) + ctx.APIErrorInternal(err) return } if task.RepoID != repo.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -207,20 +208,20 @@ func repoAssignment() func(ctx *context.APIContext) { } if err := ctx.Repo.Repository.LoadUnits(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadUnits", err) + ctx.APIErrorInternal(err) return } ctx.Repo.Permission.SetUnitsWithDefaultAccessMode(ctx.Repo.Repository.Units, ctx.Repo.Permission.AccessMode) } else { ctx.Repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return } } if !ctx.Repo.Permission.HasAnyUnitAccess() { - ctx.NotFound() + ctx.APIErrorNotFound() return } } @@ -229,7 +230,7 @@ func repoAssignment() func(ctx *context.APIContext) { func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if ctx.Package.AccessMode < accessMode && !ctx.IsUserSiteAdmin() { - ctx.Error(http.StatusForbidden, "reqPackageAccess", "user should have specific permission or be a site admin") + ctx.APIError(http.StatusForbidden, "user should have specific permission or be a site admin") return } } @@ -250,41 +251,41 @@ func checkTokenPublicOnly() func(ctx *context.APIContext) { switch { case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryRepository): if ctx.Repo.Repository != nil && ctx.Repo.Repository.IsPrivate { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public repos") + ctx.APIError(http.StatusForbidden, "token scope is limited to public repos") return } case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryIssue): if ctx.Repo.Repository != nil && ctx.Repo.Repository.IsPrivate { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public issues") + ctx.APIError(http.StatusForbidden, "token scope is limited to public issues") return } case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryOrganization): if ctx.Org.Organization != nil && ctx.Org.Organization.Visibility != api.VisibleTypePublic { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public orgs") + ctx.APIError(http.StatusForbidden, "token scope is limited to public orgs") return } if ctx.ContextUser != nil && ctx.ContextUser.IsOrganization() && ctx.ContextUser.Visibility != api.VisibleTypePublic { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public orgs") + ctx.APIError(http.StatusForbidden, "token scope is limited to public orgs") return } case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryUser): if ctx.ContextUser != nil && ctx.ContextUser.IsTokenAccessAllowed() && ctx.ContextUser.Visibility != api.VisibleTypePublic { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public users") + ctx.APIError(http.StatusForbidden, "token scope is limited to public users") return } case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryActivityPub): if ctx.ContextUser != nil && ctx.ContextUser.IsTokenAccessAllowed() && ctx.ContextUser.Visibility != api.VisibleTypePublic { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public activitypub") + ctx.APIError(http.StatusForbidden, "token scope is limited to public activitypub") return } case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryNotification): if ctx.Repo.Repository != nil && ctx.Repo.Repository.IsPrivate { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public notifications") + ctx.APIError(http.StatusForbidden, "token scope is limited to public notifications") return } case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryPackage): if ctx.Package != nil && ctx.Package.Owner.Visibility.IsPrivate() { - ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public packages") + ctx.APIError(http.StatusForbidden, "token scope is limited to public packages") return } } @@ -316,12 +317,12 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC requiredScopes := auth_model.GetRequiredScopes(requiredScopeLevel, requiredScopeCategories...) allow, err := scope.HasScope(requiredScopes...) if err != nil { - ctx.Error(http.StatusForbidden, "tokenRequiresScope", "checking scope failed: "+err.Error()) + ctx.APIError(http.StatusForbidden, "checking scope failed: "+err.Error()) return } if !allow { - ctx.Error(http.StatusForbidden, "tokenRequiresScope", fmt.Sprintf("token does not have at least one of required scope(s), required=%v, token scope=%v", requiredScopes, scope)) + ctx.APIError(http.StatusForbidden, fmt.Sprintf("token does not have at least one of required scope(s), required=%v, token scope=%v", requiredScopes, scope)) return } @@ -330,7 +331,7 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC // check if scope only applies to public resources publicOnly, err := scope.PublicOnly() if err != nil { - ctx.Error(http.StatusForbidden, "tokenRequiresScope", "parsing public resource scope failed: "+err.Error()) + ctx.APIError(http.StatusForbidden, "parsing public resource scope failed: "+err.Error()) return } @@ -350,14 +351,14 @@ func reqToken() func(ctx *context.APIContext) { if ctx.IsSigned { return } - ctx.Error(http.StatusUnauthorized, "reqToken", "token is required") + ctx.APIError(http.StatusUnauthorized, "token is required") } } func reqExploreSignIn() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if (setting.Service.RequireSignInView || setting.Service.Explore.RequireSigninView) && !ctx.IsSigned { - ctx.Error(http.StatusUnauthorized, "reqExploreSignIn", "you must be signed in to search for users") + ctx.APIError(http.StatusUnauthorized, "you must be signed in to search for users") } } } @@ -365,7 +366,7 @@ func reqExploreSignIn() func(ctx *context.APIContext) { func reqUsersExploreEnabled() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if setting.Service.Explore.DisableUsersPage { - ctx.NotFound() + ctx.APIErrorNotFound() } } } @@ -376,7 +377,7 @@ func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) { return } if !ctx.IsBasicAuth { - ctx.Error(http.StatusUnauthorized, "reqBasicAuth", "auth required") + ctx.APIError(http.StatusUnauthorized, "auth required") return } } @@ -386,7 +387,7 @@ func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) { func reqSiteAdmin() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserSiteAdmin() { - ctx.Error(http.StatusForbidden, "reqSiteAdmin", "user should be the site admin") + ctx.APIError(http.StatusForbidden, "user should be the site admin") return } } @@ -396,7 +397,7 @@ func reqSiteAdmin() func(ctx *context.APIContext) { func reqOwner() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.Repo.IsOwner() && !ctx.IsUserSiteAdmin() { - ctx.Error(http.StatusForbidden, "reqOwner", "user should be the owner of the repo") + ctx.APIError(http.StatusForbidden, "user should be the owner of the repo") return } } @@ -406,7 +407,7 @@ func reqOwner() func(ctx *context.APIContext) { func reqSelfOrAdmin() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserSiteAdmin() && ctx.ContextUser != ctx.Doer { - ctx.Error(http.StatusForbidden, "reqSelfOrAdmin", "doer should be the site admin or be same as the contextUser") + ctx.APIError(http.StatusForbidden, "doer should be the site admin or be same as the contextUser") return } } @@ -416,7 +417,7 @@ func reqSelfOrAdmin() func(ctx *context.APIContext) { func reqAdmin() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserRepoAdmin() && !ctx.IsUserSiteAdmin() { - ctx.Error(http.StatusForbidden, "reqAdmin", "user should be an owner or a collaborator with admin write of a repository") + ctx.APIError(http.StatusForbidden, "user should be an owner or a collaborator with admin write of a repository") return } } @@ -426,7 +427,7 @@ func reqAdmin() func(ctx *context.APIContext) { func reqRepoWriter(unitTypes ...unit.Type) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.IsUserRepoWriter(unitTypes) && !ctx.IsUserRepoAdmin() && !ctx.IsUserSiteAdmin() { - ctx.Error(http.StatusForbidden, "reqRepoWriter", "user should have a permission to write to a repo") + ctx.APIError(http.StatusForbidden, "user should have a permission to write to a repo") return } } @@ -436,7 +437,7 @@ func reqRepoWriter(unitTypes ...unit.Type) func(ctx *context.APIContext) { func reqRepoBranchWriter(ctx *context.APIContext) { options, ok := web.GetForm(ctx).(api.FileOptionInterface) if !ok || (!ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, options.Branch()) && !ctx.IsUserSiteAdmin()) { - ctx.Error(http.StatusForbidden, "reqRepoBranchWriter", "user should have a permission to write to this branch") + ctx.APIError(http.StatusForbidden, "user should have a permission to write to this branch") return } } @@ -445,7 +446,7 @@ func reqRepoBranchWriter(ctx *context.APIContext) { func reqRepoReader(unitType unit.Type) func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.Repo.CanRead(unitType) && !ctx.IsUserRepoAdmin() && !ctx.IsUserSiteAdmin() { - ctx.Error(http.StatusForbidden, "reqRepoReader", "user should have specific read permission or be a repo admin or a site admin") + ctx.APIError(http.StatusForbidden, "user should have specific read permission or be a repo admin or a site admin") return } } @@ -455,7 +456,7 @@ func reqRepoReader(unitType unit.Type) func(ctx *context.APIContext) { func reqAnyRepoReader() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.Repo.Permission.HasAnyUnitAccess() && !ctx.IsUserSiteAdmin() { - ctx.Error(http.StatusForbidden, "reqAnyRepoReader", "user should have any permission to read repository or permissions of site admin") + ctx.APIError(http.StatusForbidden, "user should have any permission to read repository or permissions of site admin") return } } @@ -474,19 +475,20 @@ func reqOrgOwnership() func(ctx *context.APIContext) { } else if ctx.Org.Team != nil { orgID = ctx.Org.Team.OrgID } else { - ctx.Error(http.StatusInternalServerError, "", "reqOrgOwnership: unprepared context") + setting.PanicInDevOrTesting("reqOrgOwnership: unprepared context") + ctx.APIErrorInternal(errors.New("reqOrgOwnership: unprepared context")) return } isOwner, err := organization.IsOrganizationOwner(ctx, orgID, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrganizationOwner", err) + ctx.APIErrorInternal(err) return } else if !isOwner { if ctx.Org.Organization != nil { - ctx.Error(http.StatusForbidden, "", "Must be an organization owner") + ctx.APIError(http.StatusForbidden, "Must be an organization owner") } else { - ctx.NotFound() + ctx.APIErrorNotFound() } return } @@ -500,30 +502,31 @@ func reqTeamMembership() func(ctx *context.APIContext) { return } if ctx.Org.Team == nil { - ctx.Error(http.StatusInternalServerError, "", "reqTeamMembership: unprepared context") + setting.PanicInDevOrTesting("reqTeamMembership: unprepared context") + ctx.APIErrorInternal(errors.New("reqTeamMembership: unprepared context")) return } orgID := ctx.Org.Team.OrgID isOwner, err := organization.IsOrganizationOwner(ctx, orgID, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrganizationOwner", err) + ctx.APIErrorInternal(err) return } else if isOwner { return } if isTeamMember, err := organization.IsTeamMember(ctx, orgID, ctx.Org.Team.ID, ctx.Doer.ID); err != nil { - ctx.Error(http.StatusInternalServerError, "IsTeamMember", err) + ctx.APIErrorInternal(err) return } else if !isTeamMember { isOrgMember, err := organization.IsOrganizationMember(ctx, orgID, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrganizationMember", err) + ctx.APIErrorInternal(err) } else if isOrgMember { - ctx.Error(http.StatusForbidden, "", "Must be a team member") + ctx.APIError(http.StatusForbidden, "Must be a team member") } else { - ctx.NotFound() + ctx.APIErrorNotFound() } return } @@ -543,18 +546,19 @@ func reqOrgMembership() func(ctx *context.APIContext) { } else if ctx.Org.Team != nil { orgID = ctx.Org.Team.OrgID } else { - ctx.Error(http.StatusInternalServerError, "", "reqOrgMembership: unprepared context") + setting.PanicInDevOrTesting("reqOrgMembership: unprepared context") + ctx.APIErrorInternal(errors.New("reqOrgMembership: unprepared context")) return } if isMember, err := organization.IsOrganizationMember(ctx, orgID, ctx.Doer.ID); err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrganizationMember", err) + ctx.APIErrorInternal(err) return } else if !isMember { if ctx.Org.Organization != nil { - ctx.Error(http.StatusForbidden, "", "Must be an organization member") + ctx.APIError(http.StatusForbidden, "Must be an organization member") } else { - ctx.NotFound() + ctx.APIErrorNotFound() } return } @@ -564,7 +568,7 @@ func reqOrgMembership() func(ctx *context.APIContext) { func reqGitHook() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if !ctx.Doer.CanEditGitHook() { - ctx.Error(http.StatusForbidden, "", "must be allowed to edit Git hooks") + ctx.APIError(http.StatusForbidden, "must be allowed to edit Git hooks") return } } @@ -574,7 +578,7 @@ func reqGitHook() func(ctx *context.APIContext) { func reqWebhooksEnabled() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if setting.DisableWebhooks { - ctx.Error(http.StatusForbidden, "", "webhooks disabled by administrator") + ctx.APIError(http.StatusForbidden, "webhooks disabled by administrator") return } } @@ -584,7 +588,7 @@ func reqWebhooksEnabled() func(ctx *context.APIContext) { func reqStarsEnabled() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { if setting.Repository.DisableStars { - ctx.Error(http.StatusForbidden, "", "stars disabled by administrator") + ctx.APIError(http.StatusForbidden, "stars disabled by administrator") return } } @@ -613,12 +617,12 @@ func orgAssignment(args ...bool) func(ctx *context.APIContext) { if err == nil { context.RedirectToUser(ctx.Base, ctx.PathParam("org"), redirectUserID) } else if user_model.IsErrUserRedirectNotExist(err) { - ctx.NotFound("GetOrgByName", err) + ctx.APIErrorNotFound("GetOrgByName", err) } else { - ctx.Error(http.StatusInternalServerError, "LookupUserRedirect", err) + ctx.APIErrorInternal(err) } } else { - ctx.Error(http.StatusInternalServerError, "GetOrgByName", err) + ctx.APIErrorInternal(err) } return } @@ -629,9 +633,9 @@ func orgAssignment(args ...bool) func(ctx *context.APIContext) { ctx.Org.Team, err = organization.GetTeamByID(ctx, ctx.PathParamInt64("teamid")) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetTeamById", err) + ctx.APIErrorInternal(err) } return } @@ -657,7 +661,7 @@ func mustEnableIssues(ctx *context.APIContext) { ctx.Repo.Permission) } } - ctx.NotFound() + ctx.APIErrorNotFound() return } } @@ -680,7 +684,7 @@ func mustAllowPulls(ctx *context.APIContext) { ctx.Repo.Permission) } } - ctx.NotFound() + ctx.APIErrorNotFound() return } } @@ -706,28 +710,28 @@ func mustEnableIssuesOrPulls(ctx *context.APIContext) { ctx.Repo.Permission) } } - ctx.NotFound() + ctx.APIErrorNotFound() return } } func mustEnableWiki(ctx *context.APIContext) { if !(ctx.Repo.CanRead(unit.TypeWiki)) { - ctx.NotFound() + ctx.APIErrorNotFound() return } } func mustNotBeArchived(ctx *context.APIContext) { if ctx.Repo.Repository.IsArchived { - ctx.Error(http.StatusLocked, "RepoArchived", fmt.Errorf("%s is archived", ctx.Repo.Repository.LogString())) + ctx.APIError(http.StatusLocked, fmt.Errorf("%s is archived", ctx.Repo.Repository.LogString())) return } } func mustEnableAttachments(ctx *context.APIContext) { if !setting.Attachment.Enabled { - ctx.NotFound() + ctx.APIErrorNotFound() return } } @@ -738,7 +742,7 @@ func bind[T any](_ T) any { theObj := new(T) // create a new form obj for every request but not use obj directly errs := binding.Bind(ctx.Req, theObj) if len(errs) > 0 { - ctx.Error(http.StatusUnprocessableEntity, "validationError", fmt.Sprintf("%s: %s", errs[0].FieldNames, errs[0].Error())) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("%s: %s", errs[0].FieldNames, errs[0].Error())) return } web.SetForm(ctx, theObj) @@ -766,7 +770,7 @@ func apiAuth(authMethod auth.Method) func(*context.APIContext) { return func(ctx *context.APIContext) { ar, err := common.AuthShared(ctx.Base, nil, authMethod) if err != nil { - ctx.Error(http.StatusUnauthorized, "APIAuth", err) + ctx.APIError(http.StatusUnauthorized, err) return } ctx.Doer = ar.Doer @@ -843,12 +847,12 @@ func individualPermsChecker(ctx *context.APIContext) { switch { case ctx.ContextUser.Visibility == api.VisibleTypePrivate: if ctx.Doer == nil || (ctx.ContextUser.ID != ctx.Doer.ID && !ctx.Doer.IsAdmin) { - ctx.NotFound("Visit Project", nil) + ctx.APIErrorNotFound("Visit Project", nil) return } case ctx.ContextUser.Visibility == api.VisibleTypeLimited: if ctx.Doer == nil { - ctx.NotFound("Visit Project", nil) + ctx.APIErrorNotFound("Visit Project", nil) return } } diff --git a/routers/api/v1/misc/gitignore.go b/routers/api/v1/misc/gitignore.go index b0bf00a921f88..1ff2628ce80cd 100644 --- a/routers/api/v1/misc/gitignore.go +++ b/routers/api/v1/misc/gitignore.go @@ -48,7 +48,7 @@ func GetGitignoreTemplateInfo(ctx *context.APIContext) { text, err := options.Gitignore(name) if err != nil { - ctx.NotFound() + ctx.APIErrorNotFound() return } diff --git a/routers/api/v1/misc/label_templates.go b/routers/api/v1/misc/label_templates.go index f105b4c684553..95c156c4ab759 100644 --- a/routers/api/v1/misc/label_templates.go +++ b/routers/api/v1/misc/label_templates.go @@ -52,7 +52,7 @@ func GetLabelTemplate(ctx *context.APIContext) { labels, err := repo_module.LoadTemplateLabelsByDisplayName(name) if err != nil { - ctx.NotFound() + ctx.APIErrorNotFound() return } diff --git a/routers/api/v1/misc/licenses.go b/routers/api/v1/misc/licenses.go index d99b276232d41..107d53cad79da 100644 --- a/routers/api/v1/misc/licenses.go +++ b/routers/api/v1/misc/licenses.go @@ -59,7 +59,7 @@ func GetLicenseTemplateInfo(ctx *context.APIContext) { text, err := options.License(name) if err != nil { - ctx.NotFound() + ctx.APIErrorNotFound() return } diff --git a/routers/api/v1/misc/markup.go b/routers/api/v1/misc/markup.go index 7b3633552fde5..0cd4b8c5c5aa7 100644 --- a/routers/api/v1/misc/markup.go +++ b/routers/api/v1/misc/markup.go @@ -38,7 +38,7 @@ func Markup(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.MarkupOption) if ctx.HasAPIError() { - ctx.Error(http.StatusUnprocessableEntity, "", ctx.GetErrMsg()) + ctx.APIError(http.StatusUnprocessableEntity, ctx.GetErrMsg()) return } @@ -69,7 +69,7 @@ func Markdown(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.MarkdownOption) if ctx.HasAPIError() { - ctx.Error(http.StatusUnprocessableEntity, "", ctx.GetErrMsg()) + ctx.APIError(http.StatusUnprocessableEntity, ctx.GetErrMsg()) return } @@ -100,7 +100,7 @@ func MarkdownRaw(ctx *context.APIContext) { // "$ref": "#/responses/validationError" defer ctx.Req.Body.Close() if err := markdown.RenderRaw(markup.NewRenderContext(ctx), ctx.Req.Body, ctx.Resp); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } } diff --git a/routers/api/v1/misc/nodeinfo.go b/routers/api/v1/misc/nodeinfo.go index 597372478260d..ffe50e9fda462 100644 --- a/routers/api/v1/misc/nodeinfo.go +++ b/routers/api/v1/misc/nodeinfo.go @@ -52,7 +52,7 @@ func NodeInfo(ctx *context.APIContext) { } if err := ctx.Cache.PutJSON(cacheKeyNodeInfoUsage, nodeInfoUsage, 180); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } } diff --git a/routers/api/v1/misc/signing.go b/routers/api/v1/misc/signing.go index 24a46c1e704ca..667396e39ca36 100644 --- a/routers/api/v1/misc/signing.go +++ b/routers/api/v1/misc/signing.go @@ -5,7 +5,6 @@ package misc import ( "fmt" - "net/http" asymkey_service "code.gitea.io/gitea/services/asymkey" "code.gitea.io/gitea/services/context" @@ -53,11 +52,11 @@ func SigningKey(ctx *context.APIContext) { content, err := asymkey_service.PublicSigningKey(ctx, path) if err != nil { - ctx.Error(http.StatusInternalServerError, "gpg export", err) + ctx.APIErrorInternal(err) return } _, err = ctx.Write([]byte(content)) if err != nil { - ctx.Error(http.StatusInternalServerError, "gpg export", fmt.Errorf("Error writing key content %w", err)) + ctx.APIErrorInternal(fmt.Errorf("Error writing key content %w", err)) } } diff --git a/routers/api/v1/notify/notifications.go b/routers/api/v1/notify/notifications.go index 46b3c7f5e7582..4e4c7dc6dddd7 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.Error(http.StatusUnprocessableEntity, "db.Count[activities_model.Notification]", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } @@ -38,7 +38,7 @@ func NewAvailable(ctx *context.APIContext) { func getFindNotificationOptions(ctx *context.APIContext) *activities_model.FindNotificationOptions { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return nil } opts := &activities_model.FindNotificationOptions{ diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go index 1744426ee8eb9..e87054e26cda2 100644 --- a/routers/api/v1/notify/repo.go +++ b/routers/api/v1/notify/repo.go @@ -110,18 +110,18 @@ func ListRepoNotifications(ctx *context.APIContext) { totalCount, err := db.Count[activities_model.Notification](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } nl, err := db.Find[activities_model.Notification](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } err = activities_model.NotificationList(nl).LoadAttributes(ctx) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -183,7 +183,7 @@ func ReadRepoNotifications(ctx *context.APIContext) { if len(qLastRead) > 0 { tmpLastRead, err := time.Parse(time.RFC3339, qLastRead) if err != nil { - ctx.Error(http.StatusBadRequest, "Parse", err) + ctx.APIError(http.StatusBadRequest, err) return } if !tmpLastRead.IsZero() { @@ -203,7 +203,7 @@ func ReadRepoNotifications(ctx *context.APIContext) { } nl, err := db.Find[activities_model.Notification](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -217,7 +217,7 @@ func ReadRepoNotifications(ctx *context.APIContext) { for _, n := range nl { notif, err := activities_model.SetNotificationStatus(ctx, n.ID, ctx.Doer, targetStatus) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } _ = notif.LoadAttributes(ctx) diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go index 58a38cfd18c1f..dd77e4aae4d7f 100644 --- a/routers/api/v1/notify/threads.go +++ b/routers/api/v1/notify/threads.go @@ -42,7 +42,7 @@ func GetThread(ctx *context.APIContext) { return } if err := n.LoadAttributes(ctx); err != nil && !issues_model.IsErrCommentNotExist(err) { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -90,11 +90,11 @@ func ReadThread(ctx *context.APIContext) { notif, err := activities_model.SetNotificationStatus(ctx, n.ID, ctx.Doer, targetStatus) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if err = notif.LoadAttributes(ctx); err != nil && !issues_model.IsErrCommentNotExist(err) { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusResetContent, convert.ToNotificationThread(ctx, notif)) @@ -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.Error(http.StatusNotFound, "GetNotificationByID", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) } return nil } if n.UserID != ctx.Doer.ID && !ctx.Doer.IsAdmin { - ctx.Error(http.StatusForbidden, "GetNotificationByID", fmt.Errorf("only user itself and admin are allowed to read/change this thread %d", n.ID)) + ctx.APIError(http.StatusForbidden, fmt.Errorf("only user itself and admin are allowed to read/change this thread %d", n.ID)) return nil } return n diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go index 879f484cceef7..3ebb678835195 100644 --- a/routers/api/v1/notify/user.go +++ b/routers/api/v1/notify/user.go @@ -71,18 +71,18 @@ func ListNotifications(ctx *context.APIContext) { totalCount, err := db.Count[activities_model.Notification](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } nl, err := db.Find[activities_model.Notification](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } err = activities_model.NotificationList(nl).LoadAttributes(ctx) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -133,7 +133,7 @@ func ReadNotifications(ctx *context.APIContext) { if len(qLastRead) > 0 { tmpLastRead, err := time.Parse(time.RFC3339, qLastRead) if err != nil { - ctx.Error(http.StatusBadRequest, "Parse", err) + ctx.APIError(http.StatusBadRequest, err) return } if !tmpLastRead.IsZero() { @@ -150,7 +150,7 @@ func ReadNotifications(ctx *context.APIContext) { } nl, err := db.Find[activities_model.Notification](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -164,7 +164,7 @@ func ReadNotifications(ctx *context.APIContext) { for _, n := range nl { notif, err := activities_model.SetNotificationStatus(ctx, n.ID, ctx.Doer, targetStatus) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } _ = notif.LoadAttributes(ctx) diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go index 05919c523439b..d9bdb3ab48c26 100644 --- a/routers/api/v1/org/action.go +++ b/routers/api/v1/org/action.go @@ -54,7 +54,7 @@ func (Action) ListActionsSecrets(ctx *context.APIContext) { secrets, count, err := db.FindAndCount[secret_model.Secret](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -109,11 +109,11 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) { _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Org.Organization.ID, 0, ctx.PathParam("secretname"), opt.Data) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "CreateOrUpdateSecret", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateOrUpdateSecret", err) + ctx.APIErrorInternal(err) } return } @@ -156,11 +156,11 @@ 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.Error(http.StatusBadRequest, "DeleteSecret", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "DeleteSecret", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "DeleteSecret", err) + ctx.APIErrorInternal(err) } return } @@ -223,7 +223,7 @@ func (Action) ListVariables(ctx *context.APIContext) { ListOptions: utils.GetListOptions(ctx), }) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindVariables", err) + ctx.APIErrorInternal(err) return } @@ -273,9 +273,9 @@ func (Action) GetVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "GetVariable", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetVariable", err) + ctx.APIErrorInternal(err) } return } @@ -322,11 +322,11 @@ 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.Error(http.StatusBadRequest, "DeleteVariableByName", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "DeleteVariableByName", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "DeleteVariableByName", err) + ctx.APIErrorInternal(err) } return } @@ -378,19 +378,19 @@ func (Action) CreateVariable(ctx *context.APIContext) { Name: variableName, }) if err != nil && !errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusInternalServerError, "GetVariable", err) + ctx.APIErrorInternal(err) return } if v != nil && v.ID > 0 { - ctx.Error(http.StatusConflict, "VariableNameAlreadyExists", util.NewAlreadyExistErrorf("variable name %s already exists", variableName)) + ctx.APIError(http.StatusConflict, util.NewAlreadyExistErrorf("variable name %s already exists", variableName)) return } if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusBadRequest, "CreateVariable", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateVariable", err) + ctx.APIErrorInternal(err) } return } @@ -440,9 +440,9 @@ func (Action) UpdateVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "GetVariable", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetVariable", err) + ctx.APIErrorInternal(err) } return } @@ -456,9 +456,9 @@ func (Action) UpdateVariable(ctx *context.APIContext) { if _, err := actions_service.UpdateVariableNameData(ctx, v); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusBadRequest, "UpdateVariable", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "UpdateVariable", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/org/avatar.go b/routers/api/v1/org/avatar.go index f11eb6c1cd135..0eb771b2cd389 100644 --- a/routers/api/v1/org/avatar.go +++ b/routers/api/v1/org/avatar.go @@ -39,13 +39,13 @@ func UpdateAvatar(ctx *context.APIContext) { content, err := base64.StdEncoding.DecodeString(form.Image) if err != nil { - ctx.Error(http.StatusBadRequest, "DecodeImage", err) + ctx.APIError(http.StatusBadRequest, err) return } err = user_service.UploadAvatar(ctx, ctx.Org.Organization.AsUser(), content) if err != nil { - ctx.Error(http.StatusInternalServerError, "UploadAvatar", err) + ctx.APIErrorInternal(err) return } @@ -72,7 +72,7 @@ func DeleteAvatar(ctx *context.APIContext) { // "$ref": "#/responses/notFound" err := user_service.DeleteAvatar(ctx, ctx.Org.Organization.AsUser()) if err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteAvatar", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/org/hook.go b/routers/api/v1/org/hook.go index df82f4e5a2b38..f9e0684a97b13 100644 --- a/routers/api/v1/org/hook.go +++ b/routers/api/v1/org/hook.go @@ -78,7 +78,7 @@ func GetHook(ctx *context.APIContext) { apiHook, err := webhook_service.ToHook(ctx.ContextUser.HomeLink(), hook) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, apiHook) diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go index 2a9bd92e878d8..b5b70bdc7dc21 100644 --- a/routers/api/v1/org/label.go +++ b/routers/api/v1/org/label.go @@ -46,13 +46,13 @@ func ListLabels(ctx *context.APIContext) { labels, err := issues_model.GetLabelsByOrgID(ctx, ctx.Org.Organization.ID, ctx.FormString("sort"), utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelsByOrgID", err) + ctx.APIErrorInternal(err) return } count, err := issues_model.CountLabelsByOrgID(ctx, ctx.Org.Organization.ID) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -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.Error(http.StatusUnprocessableEntity, "Color", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } form.Color = color @@ -103,7 +103,7 @@ func CreateLabel(ctx *context.APIContext) { Description: form.Description, } if err := issues_model.NewLabel(ctx, label); err != nil { - ctx.Error(http.StatusInternalServerError, "NewLabel", err) + ctx.APIErrorInternal(err) return } @@ -147,9 +147,9 @@ func GetLabel(ctx *context.APIContext) { } if err != nil { if issues_model.IsErrOrgLabelNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetLabelByOrgID", err) + ctx.APIErrorInternal(err) } return } @@ -193,9 +193,9 @@ func EditLabel(ctx *context.APIContext) { l, err := issues_model.GetLabelInOrgByID(ctx, ctx.Org.Organization.ID, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrOrgLabelNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) + ctx.APIErrorInternal(err) } return } @@ -209,7 +209,7 @@ func EditLabel(ctx *context.APIContext) { if form.Color != nil { color, err := label.NormalizeColor(*form.Color) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "Color", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } l.Color = color @@ -219,7 +219,7 @@ func EditLabel(ctx *context.APIContext) { } l.SetArchived(form.IsArchived != nil && *form.IsArchived) if err := issues_model.UpdateLabel(ctx, l); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateLabel", err) + ctx.APIErrorInternal(err) return } @@ -250,7 +250,7 @@ func DeleteLabel(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if err := issues_model.DeleteLabel(ctx, ctx.Org.Organization.ID, ctx.PathParamInt64("id")); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteLabel", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/org/member.go b/routers/api/v1/org/member.go index 23c7da3d968d4..2663d78b73bc0 100644 --- a/routers/api/v1/org/member.go +++ b/routers/api/v1/org/member.go @@ -28,13 +28,13 @@ func listMembers(ctx *context.APIContext, isMember bool) { count, err := organization.CountOrgMembers(ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } members, _, err := organization.FindOrgMembers(ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -82,7 +82,7 @@ func ListMembers(ctx *context.APIContext) { if ctx.Doer != nil { isMember, err = ctx.Org.Organization.IsOrgMember(ctx, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrgMember", err) + ctx.APIErrorInternal(err) return } } @@ -150,20 +150,20 @@ func IsMember(ctx *context.APIContext) { if ctx.Doer != nil { userIsMember, err := ctx.Org.Organization.IsOrgMember(ctx, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrgMember", err) + ctx.APIErrorInternal(err) return } else if userIsMember || ctx.Doer.IsAdmin { userToCheckIsMember, err := ctx.Org.Organization.IsOrgMember(ctx, userToCheck.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrgMember", err) + ctx.APIErrorInternal(err) } else if userToCheckIsMember { ctx.Status(http.StatusNoContent) } else { - ctx.NotFound() + ctx.APIErrorNotFound() } return } else if ctx.Doer.ID == userToCheck.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } } @@ -200,13 +200,13 @@ func IsPublicMember(ctx *context.APIContext) { } is, err := organization.IsPublicMembership(ctx, ctx.Org.Organization.ID, userToCheck.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsPublicMembership", err) + ctx.APIErrorInternal(err) return } if is { ctx.Status(http.StatusNoContent) } else { - ctx.NotFound() + ctx.APIErrorNotFound() } } @@ -241,12 +241,12 @@ func PublicizeMember(ctx *context.APIContext) { return } if userToPublicize.ID != ctx.Doer.ID { - ctx.Error(http.StatusForbidden, "", "Cannot publicize another member") + ctx.APIError(http.StatusForbidden, "Cannot publicize another member") return } err := organization.ChangeOrgUserStatus(ctx, ctx.Org.Organization.ID, userToPublicize.ID, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "ChangeOrgUserStatus", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -283,12 +283,12 @@ func ConcealMember(ctx *context.APIContext) { return } if userToConceal.ID != ctx.Doer.ID { - ctx.Error(http.StatusForbidden, "", "Cannot conceal another member") + ctx.APIError(http.StatusForbidden, "Cannot conceal another member") return } err := organization.ChangeOrgUserStatus(ctx, ctx.Org.Organization.ID, userToConceal.ID, false) if err != nil { - ctx.Error(http.StatusInternalServerError, "ChangeOrgUserStatus", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -323,7 +323,7 @@ func DeleteMember(ctx *context.APIContext) { return } if err := org_service.RemoveOrgUser(ctx, ctx.Org.Organization, member); err != nil { - ctx.Error(http.StatusInternalServerError, "RemoveOrgUser", err) + ctx.APIErrorInternal(err) } ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index 2fcba0bf1aef8..c9208f4757de4 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -35,7 +35,7 @@ func listUserOrgs(ctx *context.APIContext, u *user_model.User) { } orgs, maxResults, err := db.FindAndCount[organization.Organization](ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "db.FindAndCount[organization.Organization]", err) + ctx.APIErrorInternal(err) return } @@ -138,14 +138,14 @@ func GetUserOrgsPermissions(ctx *context.APIContext) { op := api.OrganizationPermissions{} if !organization.HasOrgOrUserVisible(ctx, o, ctx.ContextUser) { - ctx.NotFound("HasOrgOrUserVisible", nil) + ctx.APIErrorNotFound("HasOrgOrUserVisible", nil) return } org := organization.OrgFromUser(o) authorizeLevel, err := org.GetOrgUserMaxAuthorizeLevel(ctx, ctx.ContextUser.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetOrgUserAuthorizeLevel", err) + ctx.APIErrorInternal(err) return } @@ -164,7 +164,7 @@ func GetUserOrgsPermissions(ctx *context.APIContext) { op.CanCreateRepository, err = org.CanCreateOrgRepo(ctx, ctx.ContextUser.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "CanCreateOrgRepo", err) + ctx.APIErrorInternal(err) return } @@ -209,7 +209,7 @@ func GetAll(ctx *context.APIContext) { Visible: vMode, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchOrganizations", err) + ctx.APIErrorInternal(err) return } orgs := make([]*api.Organization, len(publicOrgs)) @@ -245,7 +245,7 @@ func Create(ctx *context.APIContext) { // "$ref": "#/responses/validationError" form := web.GetForm(ctx).(*api.CreateOrgOption) if !ctx.Doer.CanCreateOrganization() { - ctx.Error(http.StatusForbidden, "Create organization not allowed", nil) + ctx.APIError(http.StatusForbidden, nil) return } @@ -271,9 +271,9 @@ func Create(ctx *context.APIContext) { db.IsErrNameReserved(err) || db.IsErrNameCharsNotAllowed(err) || db.IsErrNamePatternNotAllowed(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateOrganization", err) + ctx.APIErrorInternal(err) } return } @@ -301,7 +301,7 @@ func Get(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !organization.HasOrgOrUserVisible(ctx, ctx.Org.Organization.AsUser(), ctx.Doer) { - ctx.NotFound("HasOrgOrUserVisible", nil) + ctx.APIErrorNotFound("HasOrgOrUserVisible", nil) return } @@ -344,9 +344,9 @@ func Rename(ctx *context.APIContext) { orgUser := ctx.Org.Organization.AsUser() if err := user_service.RenameUser(ctx, orgUser, form.NewName); err != nil { if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) { - ctx.Error(http.StatusUnprocessableEntity, "RenameOrg", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.ServerError("RenameOrg", err) + ctx.APIErrorInternal(err) } return } @@ -383,7 +383,7 @@ func Edit(ctx *context.APIContext) { if form.Email != "" { if err := user_service.ReplacePrimaryEmailAddress(ctx, ctx.Org.Organization.AsUser(), form.Email); err != nil { - ctx.Error(http.StatusInternalServerError, "ReplacePrimaryEmailAddress", err) + ctx.APIErrorInternal(err) return } } @@ -397,7 +397,7 @@ func Edit(ctx *context.APIContext) { RepoAdminChangeTeamAccess: optional.FromPtr(form.RepoAdminChangeTeamAccess), } if err := user_service.UpdateUser(ctx, ctx.Org.Organization.AsUser(), opts); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateUser", err) + ctx.APIErrorInternal(err) return } @@ -424,7 +424,7 @@ func Delete(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if err := org.DeleteOrganization(ctx, ctx.Org.Organization, false); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteOrganization", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -469,7 +469,7 @@ func ListOrgActivityFeeds(ctx *context.APIContext) { org := organization.OrgFromUser(ctx.ContextUser) isMember, err := org.IsOrgMember(ctx, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrgMember", err) + ctx.APIErrorInternal(err) return } includePrivate = isMember @@ -488,7 +488,7 @@ func ListOrgActivityFeeds(ctx *context.APIContext) { feeds, count, err := feed_service.GetFeeds(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetFeeds", err) + ctx.APIErrorInternal(err) return } ctx.SetTotalCountHeader(count) diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index 7f44f6ed95db9..f70e5dd23515c 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -59,13 +59,13 @@ func ListTeams(ctx *context.APIContext) { OrgID: ctx.Org.Organization.ID, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "LoadTeams", err) + ctx.APIErrorInternal(err) return } apiTeams, err := convert.ToTeams(ctx, teams, false) if err != nil { - ctx.Error(http.StatusInternalServerError, "ConvertToTeams", err) + ctx.APIErrorInternal(err) return } @@ -98,13 +98,13 @@ func ListUserTeams(ctx *context.APIContext) { UserID: ctx.Doer.ID, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserTeams", err) + ctx.APIErrorInternal(err) return } apiTeams, err := convert.ToTeams(ctx, teams, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "ConvertToTeams", err) + ctx.APIErrorInternal(err) return } @@ -134,7 +134,7 @@ func GetTeam(ctx *context.APIContext) { apiTeam, err := convert.ToTeam(ctx, ctx.Org.Team, true) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -233,7 +233,7 @@ func CreateTeam(ctx *context.APIContext) { } else if len(form.Units) > 0 { attachTeamUnits(team, form.Units) } else { - ctx.Error(http.StatusInternalServerError, "getTeamUnits", errors.New("units permission should not be empty")) + ctx.APIErrorInternal(errors.New("units permission should not be empty")) return } } else { @@ -242,16 +242,16 @@ func CreateTeam(ctx *context.APIContext) { if err := org_service.NewTeam(ctx, team); err != nil { if organization.IsErrTeamAlreadyExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "NewTeam", err) + ctx.APIErrorInternal(err) } return } apiTeam, err := convert.ToTeam(ctx, team, true) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusCreated, apiTeam) @@ -285,7 +285,7 @@ func EditTeam(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.EditTeamOption) team := ctx.Org.Team if err := team.LoadUnits(ctx); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -332,13 +332,13 @@ func EditTeam(ctx *context.APIContext) { } if err := org_service.UpdateTeam(ctx, team, isAuthChanged, isIncludeAllChanged); err != nil { - ctx.Error(http.StatusInternalServerError, "EditTeam", err) + ctx.APIErrorInternal(err) return } apiTeam, err := convert.ToTeam(ctx, team) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, apiTeam) @@ -363,7 +363,7 @@ func DeleteTeam(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if err := org_service.DeleteTeam(ctx, ctx.Org.Team); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteTeam", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -399,10 +399,10 @@ func GetTeamMembers(ctx *context.APIContext) { isMember, err := organization.IsOrganizationMember(ctx, ctx.Org.Team.OrgID, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrganizationMember", err) + ctx.APIErrorInternal(err) return } else if !isMember && !ctx.Doer.IsAdmin { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -411,7 +411,7 @@ func GetTeamMembers(ctx *context.APIContext) { TeamID: ctx.Org.Team.ID, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetTeamMembers", err) + ctx.APIErrorInternal(err) return } @@ -456,10 +456,10 @@ func GetTeamMember(ctx *context.APIContext) { teamID := ctx.PathParamInt64("teamid") isTeamMember, err := organization.IsUserInTeams(ctx, u.ID, []int64{teamID}) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsUserInTeams", err) + ctx.APIErrorInternal(err) return } else if !isTeamMember { - ctx.NotFound() + ctx.APIErrorNotFound() return } ctx.JSON(http.StatusOK, convert.ToUser(ctx, u, ctx.Doer)) @@ -498,9 +498,9 @@ 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.Error(http.StatusForbidden, "AddTeamMember", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "AddTeamMember", err) + ctx.APIErrorInternal(err) } return } @@ -538,7 +538,7 @@ func RemoveTeamMember(ctx *context.APIContext) { } if err := org_service.RemoveTeamMember(ctx, ctx.Org.Team, u); err != nil { - ctx.Error(http.StatusInternalServerError, "RemoveTeamMember", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -578,14 +578,14 @@ func GetTeamRepos(ctx *context.APIContext) { TeamID: team.ID, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetTeamRepositories", err) + ctx.APIErrorInternal(err) return } repos := make([]*api.Repository, len(teamRepos)) for i, repo := range teamRepos { permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return } repos[i] = convert.ToRepo(ctx, repo, permission) @@ -630,13 +630,13 @@ func GetTeamRepo(ctx *context.APIContext) { } if !organization.HasTeamRepo(ctx, ctx.Org.Team.OrgID, ctx.Org.Team.ID, repo.ID) { - ctx.NotFound() + ctx.APIErrorNotFound() return } permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetTeamRepos", err) + ctx.APIErrorInternal(err) return } @@ -648,9 +648,9 @@ func getRepositoryByParams(ctx *context.APIContext) *repo_model.Repository { repo, err := repo_model.GetRepositoryByName(ctx, ctx.Org.Team.OrgID, ctx.PathParam("reponame")) if err != nil { if repo_model.IsErrRepoNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetRepositoryByName", err) + ctx.APIErrorInternal(err) } return nil } @@ -694,14 +694,14 @@ func AddTeamRepository(ctx *context.APIContext) { return } if access, err := access_model.AccessLevel(ctx, ctx.Doer, repo); err != nil { - ctx.Error(http.StatusInternalServerError, "AccessLevel", err) + ctx.APIErrorInternal(err) return } else if access < perm.AccessModeAdmin { - ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository") + ctx.APIError(http.StatusForbidden, "Must have admin-level access to the repository") return } if err := repo_service.TeamAddRepository(ctx, ctx.Org.Team, repo); err != nil { - ctx.Error(http.StatusInternalServerError, "TeamAddRepository", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -746,14 +746,14 @@ func RemoveTeamRepository(ctx *context.APIContext) { return } if access, err := access_model.AccessLevel(ctx, ctx.Doer, repo); err != nil { - ctx.Error(http.StatusInternalServerError, "AccessLevel", err) + ctx.APIErrorInternal(err) return } else if access < perm.AccessModeAdmin { - ctx.Error(http.StatusForbidden, "", "Must have admin-level access to the repository") + ctx.APIError(http.StatusForbidden, "Must have admin-level access to the repository") return } if err := repo_service.RemoveRepositoryFromTeam(ctx, ctx.Org.Team, repo.ID); err != nil { - ctx.Error(http.StatusInternalServerError, "RemoveRepository", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -829,7 +829,7 @@ func SearchTeam(ctx *context.APIContext) { apiTeams, err := convert.ToTeams(ctx, teams, false) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -885,7 +885,7 @@ func ListTeamActivityFeeds(ctx *context.APIContext) { feeds, count, err := feed_service.GetFeeds(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetFeeds", err) + ctx.APIErrorInternal(err) return } ctx.SetTotalCountHeader(count) diff --git a/routers/api/v1/packages/package.go b/routers/api/v1/packages/package.go index 626a34af8629b..f869519344508 100644 --- a/routers/api/v1/packages/package.go +++ b/routers/api/v1/packages/package.go @@ -67,13 +67,13 @@ func ListPackages(ctx *context.APIContext) { Paginator: &listOptions, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchVersions", err) + ctx.APIErrorInternal(err) return } pds, err := packages.GetPackageDescriptors(ctx, pvs) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetPackageDescriptors", err) + ctx.APIErrorInternal(err) return } @@ -81,7 +81,7 @@ func ListPackages(ctx *context.APIContext) { for _, pd := range pds { apiPackage, err := convert.ToPackage(ctx, pd, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "Error converting package for api", err) + ctx.APIErrorInternal(err) return } apiPackages = append(apiPackages, apiPackage) @@ -128,7 +128,7 @@ func GetPackage(ctx *context.APIContext) { apiPackage, err := convert.ToPackage(ctx, ctx.Package.Descriptor, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "Error converting package for api", err) + ctx.APIErrorInternal(err) return } @@ -169,7 +169,7 @@ func DeletePackage(ctx *context.APIContext) { err := packages_service.RemovePackageVersion(ctx, ctx.Doer, ctx.Package.Descriptor.Version) if err != nil { - ctx.Error(http.StatusInternalServerError, "RemovePackageVersion", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -252,9 +252,9 @@ 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.Error(http.StatusNotFound, "GetPackageByName", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetPackageByName", err) + ctx.APIErrorInternal(err) } return } @@ -262,9 +262,9 @@ 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.Error(http.StatusNotFound, "GetRepositoryByName", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetRepositoryByName", err) + ctx.APIErrorInternal(err) } return } @@ -273,11 +273,11 @@ func LinkPackage(ctx *context.APIContext) { if err != nil { switch { case errors.Is(err, util.ErrInvalidArgument): - ctx.Error(http.StatusBadRequest, "LinkToRepository", err) + ctx.APIError(http.StatusBadRequest, err) case errors.Is(err, util.ErrPermissionDenied): - ctx.Error(http.StatusForbidden, "LinkToRepository", err) + ctx.APIError(http.StatusForbidden, err) default: - ctx.Error(http.StatusInternalServerError, "LinkToRepository", err) + ctx.APIErrorInternal(err) } return } @@ -314,9 +314,9 @@ 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.Error(http.StatusNotFound, "GetPackageByName", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetPackageByName", err) + ctx.APIErrorInternal(err) } return } @@ -325,11 +325,11 @@ func UnlinkPackage(ctx *context.APIContext) { if err != nil { switch { case errors.Is(err, util.ErrPermissionDenied): - ctx.Error(http.StatusForbidden, "UnlinkFromRepository", err) + ctx.APIError(http.StatusForbidden, err) case errors.Is(err, util.ErrInvalidArgument): - ctx.Error(http.StatusBadRequest, "UnlinkFromRepository", err) + ctx.APIError(http.StatusBadRequest, err) default: - ctx.Error(http.StatusInternalServerError, "UnlinkFromRepository", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 480e29cfd334f..6b4ce37fcf4a2 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -77,7 +77,7 @@ func (Action) ListActionsSecrets(ctx *context.APIContext) { secrets, count, err := db.FindAndCount[secret_model.Secret](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -139,11 +139,11 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) { _, created, err := secret_service.CreateOrUpdateSecret(ctx, 0, repo.ID, ctx.PathParam("secretname"), opt.Data) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "CreateOrUpdateSecret", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateOrUpdateSecret", err) + ctx.APIErrorInternal(err) } return } @@ -193,11 +193,11 @@ 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.Error(http.StatusBadRequest, "DeleteSecret", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "DeleteSecret", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "DeleteSecret", err) + ctx.APIErrorInternal(err) } return } @@ -241,9 +241,9 @@ func (Action) GetVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "GetVariable", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetVariable", err) + ctx.APIErrorInternal(err) } return } @@ -295,11 +295,11 @@ 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.Error(http.StatusBadRequest, "DeleteVariableByName", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "DeleteVariableByName", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "DeleteVariableByName", err) + ctx.APIErrorInternal(err) } return } @@ -354,19 +354,19 @@ func (Action) CreateVariable(ctx *context.APIContext) { Name: variableName, }) if err != nil && !errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusInternalServerError, "GetVariable", err) + ctx.APIErrorInternal(err) return } if v != nil && v.ID > 0 { - ctx.Error(http.StatusConflict, "VariableNameAlreadyExists", util.NewAlreadyExistErrorf("variable name %s already exists", variableName)) + ctx.APIError(http.StatusConflict, util.NewAlreadyExistErrorf("variable name %s already exists", variableName)) return } if _, err := actions_service.CreateVariable(ctx, 0, repoID, variableName, opt.Value); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusBadRequest, "CreateVariable", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateVariable", err) + ctx.APIErrorInternal(err) } return } @@ -419,9 +419,9 @@ func (Action) UpdateVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "GetVariable", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetVariable", err) + ctx.APIErrorInternal(err) } return } @@ -435,9 +435,9 @@ func (Action) UpdateVariable(ctx *context.APIContext) { if _, err := actions_service.UpdateVariableNameData(ctx, v); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusBadRequest, "UpdateVariable", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "UpdateVariable", err) + ctx.APIErrorInternal(err) } return } @@ -484,7 +484,7 @@ func (Action) ListVariables(ctx *context.APIContext) { ListOptions: utils.GetListOptions(ctx), }) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindVariables", err) + ctx.APIErrorInternal(err) return } @@ -581,7 +581,7 @@ func ListActionTasks(ctx *context.APIContext) { RepoID: ctx.Repo.Repository.ID, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "ListActionTasks", err) + ctx.APIErrorInternal(err) return } @@ -592,7 +592,7 @@ func ListActionTasks(ctx *context.APIContext) { for i := range tasks { convertedTask, err := convert.ToActionTask(ctx, tasks[i]) if err != nil { - ctx.Error(http.StatusInternalServerError, "ToActionTask", err) + ctx.APIErrorInternal(err) return } res.Entries[i] = convertedTask @@ -634,7 +634,7 @@ func ActionsListRepositoryWorkflows(ctx *context.APIContext) { workflows, err := actions_service.ListActionWorkflows(ctx) if err != nil { - ctx.Error(http.StatusInternalServerError, "ListActionWorkflows", err) + ctx.APIErrorInternal(err) return } @@ -681,9 +681,9 @@ func ActionsGetWorkflow(ctx *context.APIContext) { workflow, err := actions_service.GetActionWorkflow(ctx, workflowID) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "GetActionWorkflow", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetActionWorkflow", err) + ctx.APIErrorInternal(err) } return } @@ -729,9 +729,9 @@ func ActionsDisableWorkflow(ctx *context.APIContext) { err := actions_service.EnableOrDisableWorkflow(ctx, workflowID, false) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "DisableActionWorkflow", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "DisableActionWorkflow", err) + ctx.APIErrorInternal(err) } return } @@ -780,7 +780,7 @@ func ActionsDispatchWorkflow(ctx *context.APIContext) { workflowID := ctx.PathParam("workflow_id") opt := web.GetForm(ctx).(*api.CreateActionWorkflowDispatch) if opt.Ref == "" { - ctx.Error(http.StatusUnprocessableEntity, "MissingWorkflowParameter", util.NewInvalidArgumentErrorf("ref is required parameter")) + ctx.APIError(http.StatusUnprocessableEntity, util.NewInvalidArgumentErrorf("ref is required parameter")) return } @@ -806,11 +806,11 @@ func ActionsDispatchWorkflow(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "DispatchActionWorkflow", err) + ctx.APIError(http.StatusNotFound, err) } else if errors.Is(err, util.ErrPermissionDenied) { - ctx.Error(http.StatusForbidden, "DispatchActionWorkflow", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "DispatchActionWorkflow", err) + ctx.APIErrorInternal(err) } return } @@ -858,9 +858,9 @@ func ActionsEnableWorkflow(ctx *context.APIContext) { err := actions_service.EnableOrDisableWorkflow(ctx, workflowID, true) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "EnableActionWorkflow", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "EnableActionWorkflow", err) + ctx.APIErrorInternal(err) } return } @@ -917,7 +917,7 @@ func GetArtifactsOfRun(ctx *context.APIContext) { ListOptions: utils.GetListOptions(ctx), }) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error(), err) + ctx.APIErrorInternal(err) return } @@ -928,7 +928,7 @@ func GetArtifactsOfRun(ctx *context.APIContext) { for i := range artifacts { convertedArtifact, err := convert.ToActionArtifact(ctx.Repo.Repository, artifacts[i]) if err != nil { - ctx.Error(http.StatusInternalServerError, "ToActionArtifact", err) + ctx.APIErrorInternal(err) return } res.Entries[i] = convertedArtifact @@ -978,7 +978,7 @@ func GetArtifacts(ctx *context.APIContext) { ListOptions: utils.GetListOptions(ctx), }) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error(), err) + ctx.APIErrorInternal(err) return } @@ -989,7 +989,7 @@ func GetArtifacts(ctx *context.APIContext) { for i := range artifacts { convertedArtifact, err := convert.ToActionArtifact(ctx.Repo.Repository, artifacts[i]) if err != nil { - ctx.Error(http.StatusInternalServerError, "ToActionArtifact", err) + ctx.APIErrorInternal(err) return } res.Entries[i] = convertedArtifact @@ -1037,14 +1037,14 @@ func GetArtifact(ctx *context.APIContext) { if actions.IsArtifactV4(art) { convertedArtifact, err := convert.ToActionArtifact(ctx.Repo.Repository, art) if err != nil { - ctx.Error(http.StatusInternalServerError, "ToActionArtifact", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convertedArtifact) return } // v3 not supported due to not having one unique id - ctx.Error(http.StatusNotFound, "GetArtifact", "Artifact not found") + ctx.APIError(http.StatusNotFound, "Artifact not found") } // DeleteArtifact Deletes a specific artifact for a workflow run. @@ -1085,14 +1085,14 @@ func DeleteArtifact(ctx *context.APIContext) { if actions.IsArtifactV4(art) { if err := actions_model.SetArtifactNeedDelete(ctx, art.RunID, art.ArtifactName); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteArtifact", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) return } // v3 not supported due to not having one unique id - ctx.Error(http.StatusNotFound, "DeleteArtifact", "Artifact not found") + ctx.APIError(http.StatusNotFound, "Artifact not found") } func buildSignature(endp string, expires, artifactID int64) []byte { @@ -1152,7 +1152,7 @@ func DownloadArtifact(ctx *context.APIContext) { // if artifacts status is not uploaded-confirmed, treat it as not found if art.Status == actions_model.ArtifactStatusExpired { - ctx.Error(http.StatusNotFound, "DownloadArtifact", "Artifact has expired") + ctx.APIError(http.StatusNotFound, "Artifact has expired") return } ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.zip; filename*=UTF-8''%s.zip", url.PathEscape(art.ArtifactName), art.ArtifactName)) @@ -1163,7 +1163,7 @@ func DownloadArtifact(ctx *context.APIContext) { return } if err != nil { - ctx.Error(http.StatusInternalServerError, "DownloadArtifactV4ServeDirectOnly", err) + ctx.APIErrorInternal(err) return } @@ -1172,7 +1172,7 @@ func DownloadArtifact(ctx *context.APIContext) { return } // v3 not supported due to not having one unique id - ctx.Error(http.StatusNotFound, "DownloadArtifact", "Artifact not found") + ctx.APIError(http.StatusNotFound, "Artifact not found") } // DownloadArtifactRaw Downloads a specific artifact for a workflow run directly. @@ -1181,9 +1181,9 @@ func DownloadArtifactRaw(ctx *context.APIContext) { repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, ctx.PathParam("username"), ctx.PathParam("reponame")) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) } return } @@ -1199,18 +1199,18 @@ func DownloadArtifactRaw(ctx *context.APIContext) { expectedSig := buildSignature(buildDownloadRawEndpoint(repo, art.ID), expires, art.ID) if !hmac.Equal(sigBytes, expectedSig) { - ctx.Error(http.StatusUnauthorized, "DownloadArtifactRaw", "Error unauthorized") + ctx.APIError(http.StatusUnauthorized, "Error unauthorized") return } t := time.Unix(expires, 0) if t.Before(time.Now()) { - ctx.Error(http.StatusUnauthorized, "DownloadArtifactRaw", "Error link expired") + ctx.APIError(http.StatusUnauthorized, "Error link expired") return } // if artifacts status is not uploaded-confirmed, treat it as not found if art.Status == actions_model.ArtifactStatusExpired { - ctx.Error(http.StatusNotFound, "DownloadArtifactRaw", "Artifact has expired") + ctx.APIError(http.StatusNotFound, "Artifact has expired") return } ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.zip; filename*=UTF-8''%s.zip", url.PathEscape(art.ArtifactName), art.ArtifactName)) @@ -1218,13 +1218,13 @@ func DownloadArtifactRaw(ctx *context.APIContext) { if actions.IsArtifactV4(art) { err := actions.DownloadArtifactV4(ctx.Base, art) if err != nil { - ctx.Error(http.StatusInternalServerError, "DownloadArtifactV4", err) + ctx.APIErrorInternal(err) return } return } // v3 not supported due to not having one unique id - ctx.Error(http.StatusNotFound, "DownloadArtifactRaw", "artifact not found") + ctx.APIError(http.StatusNotFound, "artifact not found") } // Try to get the artifact by ID and check access @@ -1233,7 +1233,7 @@ func getArtifactByPathParam(ctx *context.APIContext, repo *repo_model.Repository art, ok, err := db.GetByID[actions_model.ActionArtifact](ctx, artifactID) if err != nil { - ctx.Error(http.StatusInternalServerError, "getArtifactByPathParam", err) + ctx.APIErrorInternal(err) return nil } // if artifacts status is not uploaded-confirmed, treat it as not found @@ -1241,7 +1241,7 @@ func getArtifactByPathParam(ctx *context.APIContext, repo *repo_model.Repository if !ok || art.RepoID != repo.ID || art.Status != actions_model.ArtifactStatusUploadConfirmed && art.Status != actions_model.ArtifactStatusExpired { - ctx.Error(http.StatusNotFound, "getArtifactByPathParam", "artifact not found") + ctx.APIError(http.StatusNotFound, "artifact not found") return nil } return art diff --git a/routers/api/v1/repo/avatar.go b/routers/api/v1/repo/avatar.go index 698337ffd2f17..593460586f880 100644 --- a/routers/api/v1/repo/avatar.go +++ b/routers/api/v1/repo/avatar.go @@ -44,13 +44,13 @@ func UpdateAvatar(ctx *context.APIContext) { content, err := base64.StdEncoding.DecodeString(form.Image) if err != nil { - ctx.Error(http.StatusBadRequest, "DecodeImage", err) + ctx.APIError(http.StatusBadRequest, err) return } err = repo_service.UploadAvatar(ctx, ctx.Repo.Repository, content) if err != nil { - ctx.Error(http.StatusInternalServerError, "UploadAvatar", err) + ctx.APIErrorInternal(err) } ctx.Status(http.StatusNoContent) @@ -81,7 +81,7 @@ func DeleteAvatar(ctx *context.APIContext) { // "$ref": "#/responses/notFound" err := repo_service.DeleteAvatar(ctx, ctx.Repo.Repository) if err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteAvatar", err) + ctx.APIErrorInternal(err) } ctx.Status(http.StatusNoContent) diff --git a/routers/api/v1/repo/blob.go b/routers/api/v1/repo/blob.go index f38086954b710..d1cb72f5f1f74 100644 --- a/routers/api/v1/repo/blob.go +++ b/routers/api/v1/repo/blob.go @@ -43,12 +43,12 @@ func GetBlob(ctx *context.APIContext) { sha := ctx.PathParam("sha") if len(sha) == 0 { - ctx.Error(http.StatusBadRequest, "", "sha not provided") + ctx.APIError(http.StatusBadRequest, "sha not provided") return } if blob, err := files_service.GetBlobBySHA(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, sha); err != nil { - ctx.Error(http.StatusBadRequest, "", err) + ctx.APIError(http.StatusBadRequest, err) } else { ctx.JSON(http.StatusOK, blob) } diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index a5ea752cf10e1..5430c1a266c38 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -63,28 +63,28 @@ func GetBranch(ctx *context.APIContext) { branch, err := ctx.Repo.GitRepo.GetBranch(branchName) if err != nil { if git.IsErrBranchNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetBranch", err) + ctx.APIErrorInternal(err) } return } c, err := branch.GetCommit() if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommit", err) + ctx.APIErrorInternal(err) return } branchProtection, err := git_model.GetFirstMatchProtectedBranchRule(ctx, ctx.Repo.Repository.ID, branchName) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetBranchProtection", err) + ctx.APIErrorInternal(err) return } br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branch.Name, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin()) if err != nil { - ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err) + ctx.APIErrorInternal(err) return } @@ -124,12 +124,12 @@ func DeleteBranch(ctx *context.APIContext) { // "423": // "$ref": "#/responses/repoArchivedError" if ctx.Repo.Repository.IsEmpty { - ctx.Error(http.StatusNotFound, "", "Git Repository is empty.") + ctx.APIError(http.StatusNotFound, "Git Repository is empty.") return } if ctx.Repo.Repository.IsMirror { - ctx.Error(http.StatusForbidden, "", "Git Repository is a mirror.") + ctx.APIError(http.StatusForbidden, "Git Repository is a mirror.") return } @@ -141,13 +141,13 @@ func DeleteBranch(ctx *context.APIContext) { IsDeletedBranch: optional.Some(false), }) if err != nil { - ctx.Error(http.StatusInternalServerError, "CountBranches", err) + ctx.APIErrorInternal(err) return } if totalNumOfBranches == 0 { // sync branches immediately because non-empty repository should have at least 1 branch _, err = repo_module.SyncRepoBranches(ctx, ctx.Repo.Repository.ID, 0) if err != nil { - ctx.ServerError("SyncRepoBranches", err) + ctx.APIErrorInternal(err) return } } @@ -155,13 +155,13 @@ func DeleteBranch(ctx *context.APIContext) { if err := repo_service.DeleteBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName, nil); err != nil { switch { case git.IsErrBranchNotExist(err): - ctx.NotFound(err) + ctx.APIErrorNotFound(err) case errors.Is(err, repo_service.ErrBranchIsDefault): - ctx.Error(http.StatusForbidden, "DefaultBranch", fmt.Errorf("can not delete default branch")) + ctx.APIError(http.StatusForbidden, fmt.Errorf("can not delete default branch")) case errors.Is(err, git_model.ErrBranchIsProtected): - ctx.Error(http.StatusForbidden, "IsProtectedBranch", fmt.Errorf("branch protected")) + ctx.APIError(http.StatusForbidden, fmt.Errorf("branch protected")) default: - ctx.Error(http.StatusInternalServerError, "DeleteBranch", err) + ctx.APIErrorInternal(err) } return } @@ -206,12 +206,12 @@ func CreateBranch(ctx *context.APIContext) { // "$ref": "#/responses/repoArchivedError" if ctx.Repo.Repository.IsEmpty { - ctx.Error(http.StatusNotFound, "", "Git Repository is empty.") + ctx.APIError(http.StatusNotFound, "Git Repository is empty.") return } if ctx.Repo.Repository.IsMirror { - ctx.Error(http.StatusForbidden, "", "Git Repository is a mirror.") + ctx.APIError(http.StatusForbidden, "Git Repository is a mirror.") return } @@ -223,24 +223,24 @@ func CreateBranch(ctx *context.APIContext) { if len(opt.OldRefName) > 0 { oldCommit, err = ctx.Repo.GitRepo.GetCommit(opt.OldRefName) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommit", err) + ctx.APIErrorInternal(err) return } } else if len(opt.OldBranchName) > 0 { //nolint if ctx.Repo.GitRepo.IsBranchExist(opt.OldBranchName) { //nolint oldCommit, err = ctx.Repo.GitRepo.GetBranchCommit(opt.OldBranchName) //nolint if err != nil { - ctx.Error(http.StatusInternalServerError, "GetBranchCommit", err) + ctx.APIErrorInternal(err) return } } else { - ctx.Error(http.StatusNotFound, "", "The old branch does not exist") + ctx.APIError(http.StatusNotFound, "The old branch does not exist") return } } else { oldCommit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetBranchCommit", err) + ctx.APIErrorInternal(err) return } } @@ -248,40 +248,40 @@ func CreateBranch(ctx *context.APIContext) { err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, oldCommit.ID.String(), opt.BranchName) if err != nil { if git_model.IsErrBranchNotExist(err) { - ctx.Error(http.StatusNotFound, "", "The old branch does not exist") + ctx.APIError(http.StatusNotFound, "The old branch does not exist") } else if release_service.IsErrTagAlreadyExists(err) { - ctx.Error(http.StatusConflict, "", "The branch with the same tag already exists.") + ctx.APIError(http.StatusConflict, "The branch with the same tag already exists.") } else if git_model.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) { - ctx.Error(http.StatusConflict, "", "The branch already exists.") + ctx.APIError(http.StatusConflict, "The branch already exists.") } else if git_model.IsErrBranchNameConflict(err) { - ctx.Error(http.StatusConflict, "", "The branch with the same name already exists.") + ctx.APIError(http.StatusConflict, "The branch with the same name already exists.") } else { - ctx.Error(http.StatusInternalServerError, "CreateNewBranchFromCommit", err) + ctx.APIErrorInternal(err) } return } branch, err := ctx.Repo.GitRepo.GetBranch(opt.BranchName) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetBranch", err) + ctx.APIErrorInternal(err) return } commit, err := branch.GetCommit() if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommit", err) + ctx.APIErrorInternal(err) return } branchProtection, err := git_model.GetFirstMatchProtectedBranchRule(ctx, ctx.Repo.Repository.ID, branch.Name) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetBranchProtection", err) + ctx.APIErrorInternal(err) return } br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branch.Name, commit, branchProtection, ctx.Doer, ctx.Repo.IsAdmin()) if err != nil { - ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err) + ctx.APIErrorInternal(err) return } @@ -325,7 +325,7 @@ func ListBranches(ctx *context.APIContext) { if !ctx.Repo.Repository.IsEmpty { if ctx.Repo.GitRepo == nil { - ctx.Error(http.StatusInternalServerError, "Load git repository failed", nil) + ctx.APIErrorInternal(nil) return } @@ -337,26 +337,26 @@ func ListBranches(ctx *context.APIContext) { var err error totalNumOfBranches, err = db.Count[git_model.Branch](ctx, branchOpts) if err != nil { - ctx.Error(http.StatusInternalServerError, "CountBranches", err) + ctx.APIErrorInternal(err) return } if totalNumOfBranches == 0 { // sync branches immediately because non-empty repository should have at least 1 branch totalNumOfBranches, err = repo_module.SyncRepoBranches(ctx, ctx.Repo.Repository.ID, 0) if err != nil { - ctx.ServerError("SyncRepoBranches", err) + ctx.APIErrorInternal(err) return } } rules, err := git_model.FindRepoProtectedBranchRules(ctx, ctx.Repo.Repository.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindMatchedProtectedBranchRules", err) + ctx.APIErrorInternal(err) return } branches, err := db.Find[git_model.Branch](ctx, branchOpts) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetBranches", err) + ctx.APIErrorInternal(err) return } @@ -369,14 +369,14 @@ func ListBranches(ctx *context.APIContext) { totalNumOfBranches-- continue } - ctx.Error(http.StatusInternalServerError, "GetCommit", err) + ctx.APIErrorInternal(err) return } branchProtection := rules.GetFirstMatched(branches[i].Name) apiBranch, err := convert.ToBranch(ctx, ctx.Repo.Repository, branches[i].Name, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin()) if err != nil { - ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err) + ctx.APIErrorInternal(err) return } apiBranches = append(apiBranches, apiBranch) @@ -433,12 +433,12 @@ func UpdateBranch(ctx *context.APIContext) { repo := ctx.Repo.Repository if repo.IsEmpty { - ctx.Error(http.StatusNotFound, "", "Git Repository is empty.") + ctx.APIError(http.StatusNotFound, "Git Repository is empty.") return } if repo.IsMirror { - ctx.Error(http.StatusForbidden, "", "Git Repository is a mirror.") + ctx.APIError(http.StatusForbidden, "Git Repository is a mirror.") return } @@ -446,20 +446,20 @@ func UpdateBranch(ctx *context.APIContext) { if err != nil { switch { case repo_model.IsErrUserDoesNotHaveAccessToRepo(err): - ctx.Error(http.StatusForbidden, "", "User must be a repo or site admin to rename default or protected branches.") + ctx.APIError(http.StatusForbidden, "User must be a repo or site admin to rename default or protected branches.") case errors.Is(err, git_model.ErrBranchIsProtected): - ctx.Error(http.StatusForbidden, "", "Branch is protected by glob-based protection rules.") + ctx.APIError(http.StatusForbidden, "Branch is protected by glob-based protection rules.") default: - ctx.Error(http.StatusInternalServerError, "RenameBranch", err) + ctx.APIErrorInternal(err) } return } if msg == "target_exist" { - ctx.Error(http.StatusUnprocessableEntity, "", "Cannot rename a branch using the same name or rename to a branch that already exists.") + ctx.APIError(http.StatusUnprocessableEntity, "Cannot rename a branch using the same name or rename to a branch that already exists.") return } if msg == "from_not_exist" { - ctx.Error(http.StatusNotFound, "", "Branch doesn't exist.") + ctx.APIError(http.StatusNotFound, "Branch doesn't exist.") return } @@ -499,11 +499,11 @@ func GetBranchProtection(ctx *context.APIContext) { bpName := ctx.PathParam("name") bp, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, bpName) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err) + ctx.APIErrorInternal(err) return } if bp == nil || bp.RepoID != repo.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -535,7 +535,7 @@ func ListBranchProtections(ctx *context.APIContext) { repo := ctx.Repo.Repository bps, err := git_model.FindRepoProtectedBranchRules(ctx, repo.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedBranches", err) + ctx.APIErrorInternal(err) return } apiBps := make([]*api.BranchProtection, len(bps)) @@ -590,7 +590,7 @@ func CreateBranchProtection(ctx *context.APIContext) { ruleName = form.BranchName //nolint } if len(ruleName) == 0 { - ctx.Error(http.StatusBadRequest, "both rule_name and branch_name are empty", "both rule_name and branch_name are empty") + ctx.APIError(http.StatusBadRequest, "both rule_name and branch_name are empty") return } @@ -602,10 +602,10 @@ func CreateBranchProtection(ctx *context.APIContext) { protectBranch, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, ruleName) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectBranchOfRepoByName", err) + ctx.APIErrorInternal(err) return } else if protectBranch != nil { - ctx.Error(http.StatusForbidden, "Create branch protection", "Branch protection already exist") + ctx.APIError(http.StatusForbidden, "Branch protection already exist") return } @@ -617,37 +617,37 @@ func CreateBranchProtection(ctx *context.APIContext) { whitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.PushWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err) + ctx.APIErrorInternal(err) return } forcePushAllowlistUsers, err := user_model.GetUserIDsByNames(ctx, form.ForcePushAllowlistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err) + ctx.APIErrorInternal(err) return } mergeWhitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.MergeWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err) + ctx.APIErrorInternal(err) return } approvalsWhitelistUsers, err := user_model.GetUserIDsByNames(ctx, form.ApprovalsWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err) + ctx.APIErrorInternal(err) return } var whitelistTeams, forcePushAllowlistTeams, mergeWhitelistTeams, approvalsWhitelistTeams []int64 @@ -655,37 +655,37 @@ func CreateBranchProtection(ctx *context.APIContext) { whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.PushWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err) + ctx.APIErrorInternal(err) return } forcePushAllowlistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.ForcePushAllowlistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err) + ctx.APIErrorInternal(err) return } mergeWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.MergeWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err) + ctx.APIErrorInternal(err) return } approvalsWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.ApprovalsWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err) + ctx.APIErrorInternal(err) return } } @@ -726,13 +726,13 @@ func CreateBranchProtection(ctx *context.APIContext) { ApprovalsUserIDs: approvalsWhitelistUsers, ApprovalsTeamIDs: approvalsWhitelistTeams, }); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateProtectBranch", err) + ctx.APIErrorInternal(err) return } if isBranchExist { if err := pull_service.CheckPRsForBaseBranch(ctx, ctx.Repo.Repository, ruleName); err != nil { - ctx.Error(http.StatusInternalServerError, "CheckPRsForBaseBranch", err) + ctx.APIErrorInternal(err) return } } else { @@ -740,20 +740,20 @@ func CreateBranchProtection(ctx *context.APIContext) { if ctx.Repo.GitRepo == nil { ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository) if err != nil { - ctx.Error(http.StatusInternalServerError, "OpenRepository", err) + ctx.APIErrorInternal(err) return } } // FIXME: since we only need to recheck files protected rules, we could improve this matchedBranches, err := git_model.FindAllMatchedBranches(ctx, ctx.Repo.Repository.ID, ruleName) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindAllMatchedBranches", err) + ctx.APIErrorInternal(err) return } for _, branchName := range matchedBranches { if err = pull_service.CheckPRsForBaseBranch(ctx, ctx.Repo.Repository, branchName); err != nil { - ctx.Error(http.StatusInternalServerError, "CheckPRsForBaseBranch", err) + ctx.APIErrorInternal(err) return } } @@ -763,11 +763,11 @@ func CreateBranchProtection(ctx *context.APIContext) { // Reload from db to get all whitelists bp, err := git_model.GetProtectedBranchRuleByName(ctx, ctx.Repo.Repository.ID, ruleName) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err) + ctx.APIErrorInternal(err) return } if bp == nil || bp.RepoID != ctx.Repo.Repository.ID { - ctx.Error(http.StatusInternalServerError, "New branch protection not found", err) + ctx.APIErrorInternal(err) return } @@ -817,11 +817,11 @@ func EditBranchProtection(ctx *context.APIContext) { bpName := ctx.PathParam("name") protectBranch, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, bpName) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err) + ctx.APIErrorInternal(err) return } if protectBranch == nil || protectBranch.RepoID != repo.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -932,10 +932,10 @@ func EditBranchProtection(ctx *context.APIContext) { whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.PushWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err) + ctx.APIErrorInternal(err) return } } else { @@ -945,10 +945,10 @@ func EditBranchProtection(ctx *context.APIContext) { forcePushAllowlistUsers, err = user_model.GetUserIDsByNames(ctx, form.ForcePushAllowlistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err) + ctx.APIErrorInternal(err) return } } else { @@ -958,10 +958,10 @@ func EditBranchProtection(ctx *context.APIContext) { mergeWhitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.MergeWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err) + ctx.APIErrorInternal(err) return } } else { @@ -971,10 +971,10 @@ func EditBranchProtection(ctx *context.APIContext) { approvalsWhitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.ApprovalsWhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err) + ctx.APIErrorInternal(err) return } } else { @@ -987,10 +987,10 @@ func EditBranchProtection(ctx *context.APIContext) { whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.PushWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err) + ctx.APIErrorInternal(err) return } } else { @@ -1000,10 +1000,10 @@ func EditBranchProtection(ctx *context.APIContext) { forcePushAllowlistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.ForcePushAllowlistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err) + ctx.APIErrorInternal(err) return } } else { @@ -1013,10 +1013,10 @@ func EditBranchProtection(ctx *context.APIContext) { mergeWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.MergeWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err) + ctx.APIErrorInternal(err) return } } else { @@ -1026,10 +1026,10 @@ func EditBranchProtection(ctx *context.APIContext) { approvalsWhitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.ApprovalsWhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err) + ctx.APIErrorInternal(err) return } } else { @@ -1048,7 +1048,7 @@ func EditBranchProtection(ctx *context.APIContext) { ApprovalsTeamIDs: approvalsWhitelistTeams, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateProtectBranch", err) + ctx.APIErrorInternal(err) return } @@ -1060,7 +1060,7 @@ func EditBranchProtection(ctx *context.APIContext) { if isBranchExist { if err = pull_service.CheckPRsForBaseBranch(ctx, ctx.Repo.Repository, bpName); err != nil { - ctx.Error(http.StatusInternalServerError, "CheckPrsForBaseBranch", err) + ctx.APIErrorInternal(err) return } } else { @@ -1068,7 +1068,7 @@ func EditBranchProtection(ctx *context.APIContext) { if ctx.Repo.GitRepo == nil { ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository) if err != nil { - ctx.Error(http.StatusInternalServerError, "OpenRepository", err) + ctx.APIErrorInternal(err) return } } @@ -1076,13 +1076,13 @@ func EditBranchProtection(ctx *context.APIContext) { // FIXME: since we only need to recheck files protected rules, we could improve this matchedBranches, err := git_model.FindAllMatchedBranches(ctx, ctx.Repo.Repository.ID, protectBranch.RuleName) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindAllMatchedBranches", err) + ctx.APIErrorInternal(err) return } for _, branchName := range matchedBranches { if err = pull_service.CheckPRsForBaseBranch(ctx, ctx.Repo.Repository, branchName); err != nil { - ctx.Error(http.StatusInternalServerError, "CheckPrsForBaseBranch", err) + ctx.APIErrorInternal(err) return } } @@ -1092,11 +1092,11 @@ func EditBranchProtection(ctx *context.APIContext) { // Reload from db to ensure get all whitelists bp, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, bpName) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedBranchBy", err) + ctx.APIErrorInternal(err) return } if bp == nil || bp.RepoID != ctx.Repo.Repository.ID { - ctx.Error(http.StatusInternalServerError, "New branch protection not found", err) + ctx.APIErrorInternal(err) return } @@ -1136,16 +1136,16 @@ func DeleteBranchProtection(ctx *context.APIContext) { bpName := ctx.PathParam("name") bp, err := git_model.GetProtectedBranchRuleByName(ctx, repo.ID, bpName) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedBranchByID", err) + ctx.APIErrorInternal(err) return } if bp == nil || bp.RepoID != repo.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } if err := git_model.DeleteProtectedBranch(ctx, ctx.Repo.Repository, bp.ID); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteProtectedBranch", err) + ctx.APIErrorInternal(err) return } @@ -1189,7 +1189,7 @@ func UpdateBranchProtectionPriories(ctx *context.APIContext) { repo := ctx.Repo.Repository if err := git_model.UpdateProtectBranchPriorities(ctx, repo, form.IDs); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateProtectBranchPriorities", err) + ctx.APIErrorInternal(err) return } @@ -1228,13 +1228,13 @@ func MergeUpstream(ctx *context.APIContext) { mergeStyle, err := repo_service.MergeUpstream(ctx, ctx.Doer, ctx.Repo.Repository, form.Branch) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusBadRequest, "MergeUpstream", err) + ctx.APIError(http.StatusBadRequest, err) return } else if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "MergeUpstream", err) + ctx.APIError(http.StatusNotFound, err) return } - ctx.Error(http.StatusInternalServerError, "MergeUpstream", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, &api.MergeUpstreamResponse{MergeStyle: mergeStyle}) diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index da3ee54e691de..c397d7972b56d 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -59,7 +59,7 @@ func ListCollaborators(ctx *context.APIContext) { RepoID: ctx.Repo.Repository.ID, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "ListCollaborators", err) + ctx.APIErrorInternal(err) return } @@ -106,21 +106,21 @@ func IsCollaborator(ctx *context.APIContext) { user, err := user_model.GetUserByName(ctx, ctx.PathParam("collaborator")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return } isColab, err := repo_model.IsCollaborator(ctx, ctx.Repo.Repository.ID, user.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsCollaborator", err) + ctx.APIErrorInternal(err) return } if isColab { ctx.Status(http.StatusNoContent) } else { - ctx.NotFound() + ctx.APIErrorNotFound() } } @@ -166,15 +166,15 @@ func AddOrUpdateCollaborator(ctx *context.APIContext) { collaborator, err := user_model.GetUserByName(ctx, ctx.PathParam("collaborator")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return } if !collaborator.IsActive { - ctx.Error(http.StatusInternalServerError, "InactiveCollaborator", errors.New("collaborator's account is inactive")) + ctx.APIErrorInternal(errors.New("collaborator's account is inactive")) return } @@ -185,9 +185,9 @@ 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.Error(http.StatusForbidden, "AddOrUpdateCollaborator", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "AddOrUpdateCollaborator", err) + ctx.APIErrorInternal(err) } return } @@ -229,15 +229,15 @@ func DeleteCollaborator(ctx *context.APIContext) { collaborator, err := user_model.GetUserByName(ctx, ctx.PathParam("collaborator")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return } if err := repo_service.DeleteCollaboration(ctx, ctx.Repo.Repository, collaborator); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteCollaboration", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -275,23 +275,23 @@ func GetRepoPermissions(ctx *context.APIContext) { // "$ref": "#/responses/forbidden" if !ctx.Doer.IsAdmin && ctx.Doer.LoginName != ctx.PathParam("collaborator") && !ctx.IsUserRepoAdmin() { - ctx.Error(http.StatusForbidden, "User", "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own") + ctx.APIError(http.StatusForbidden, "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own") return } collaborator, err := user_model.GetUserByName(ctx, ctx.PathParam("collaborator")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusNotFound, "GetUserByName", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return } permission, err := access_model.GetUserRepoPermission(ctx, ctx.Repo.Repository, collaborator) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return } @@ -324,13 +324,13 @@ func GetReviewers(ctx *context.APIContext) { canChooseReviewer := issue_service.CanDoerChangeReviewRequests(ctx, ctx.Doer, ctx.Repo.Repository, 0) if !canChooseReviewer { - ctx.Error(http.StatusForbidden, "GetReviewers", errors.New("doer has no permission to get reviewers")) + ctx.APIError(http.StatusForbidden, errors.New("doer has no permission to get reviewers")) return } reviewers, err := pull_service.GetReviewers(ctx, ctx.Repo.Repository, ctx.Doer.ID, 0) if err != nil { - ctx.Error(http.StatusInternalServerError, "ListCollaborators", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToUsers(ctx, ctx.Doer, reviewers)) @@ -362,7 +362,7 @@ func GetAssignees(ctx *context.APIContext) { assignees, err := repo_model.GetRepoAssignees(ctx, ctx.Repo.Repository) if err != nil { - ctx.Error(http.StatusInternalServerError, "ListCollaborators", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToUsers(ctx, ctx.Doer, assignees)) diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 3b144d0c43765..03489d777b0d8 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -65,7 +65,7 @@ func GetSingleCommit(ctx *context.APIContext) { sha := ctx.PathParam("sha") if !git.IsValidRefPattern(sha) { - ctx.Error(http.StatusUnprocessableEntity, "no valid ref or sha", fmt.Sprintf("no valid ref or sha: %s", sha)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("no valid ref or sha: %s", sha)) return } @@ -76,16 +76,16 @@ func getCommit(ctx *context.APIContext, identifier string, toCommitOpts convert. commit, err := ctx.Repo.GitRepo.GetCommit(identifier) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound(identifier) + ctx.APIErrorNotFound(identifier) return } - ctx.Error(http.StatusInternalServerError, "gitRepo.GetCommit", err) + ctx.APIErrorInternal(err) return } json, err := convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, commit, nil, toCommitOpts) if err != nil { - ctx.Error(http.StatusInternalServerError, "toCommit", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, json) @@ -182,20 +182,20 @@ func GetAllCommits(ctx *context.APIContext) { // no sha supplied - use default branch head, err := ctx.Repo.GitRepo.GetHEADBranch() if err != nil { - ctx.Error(http.StatusInternalServerError, "GetHEADBranch", err) + ctx.APIErrorInternal(err) return } baseCommit, err = ctx.Repo.GitRepo.GetBranchCommit(head.Name) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommit", err) + ctx.APIErrorInternal(err) return } } else { // get commit specified by sha baseCommit, err = ctx.Repo.GitRepo.GetCommit(sha) if err != nil { - ctx.NotFoundOrServerError("GetCommit", git.IsErrNotExist, err) + ctx.NotFoundOrServerError(err) return } } @@ -207,14 +207,14 @@ func GetAllCommits(ctx *context.APIContext) { Revision: []string{baseCommit.ID.String()}, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommitsCount", err) + ctx.APIErrorInternal(err) return } // Query commits commits, err = baseCommit.CommitsByRange(listOptions.Page, listOptions.PageSize, not) if err != nil { - ctx.Error(http.StatusInternalServerError, "CommitsByRange", err) + ctx.APIErrorInternal(err) return } } else { @@ -231,10 +231,10 @@ func GetAllCommits(ctx *context.APIContext) { }) if err != nil { - ctx.Error(http.StatusInternalServerError, "FileCommitsCount", err) + ctx.APIErrorInternal(err) return } else if commitsCountTotal == 0 { - ctx.NotFound("FileCommitsCount", nil) + ctx.APIErrorNotFound("FileCommitsCount", nil) return } @@ -246,7 +246,7 @@ func GetAllCommits(ctx *context.APIContext) { Page: listOptions.Page, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) + ctx.APIErrorInternal(err) return } } @@ -259,7 +259,7 @@ func GetAllCommits(ctx *context.APIContext) { // Create json struct apiCommits[i], err = convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, commit, userCache, convert.ParseCommitOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "toCommit", err) + ctx.APIErrorInternal(err) return } } @@ -317,10 +317,10 @@ func DownloadCommitDiffOrPatch(ctx *context.APIContext) { if err := git.GetRawDiff(ctx.Repo.GitRepo, sha, diffType, ctx.Resp); err != nil { if git.IsErrNotExist(err) { - ctx.NotFound(sha) + ctx.APIErrorNotFound(sha) return } - ctx.Error(http.StatusInternalServerError, "DownloadCommitDiffOrPatch", err) + ctx.APIErrorInternal(err) return } } @@ -357,19 +357,19 @@ 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.Error(http.StatusNotFound, "GetPullRequestByMergedCommit", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } if err = pr.LoadBaseRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadBaseRepo", err) + ctx.APIErrorInternal(err) return } if err = pr.LoadHeadRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToAPIPullRequest(ctx, pr, ctx.Doer)) diff --git a/routers/api/v1/repo/compare.go b/routers/api/v1/repo/compare.go index a1813a8a76540..6d427c8073422 100644 --- a/routers/api/v1/repo/compare.go +++ b/routers/api/v1/repo/compare.go @@ -47,7 +47,7 @@ func CompareDiff(ctx *context.APIContext) { var err error ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository) if err != nil { - ctx.Error(http.StatusInternalServerError, "OpenRepository", err) + ctx.APIErrorInternal(err) return } } @@ -82,7 +82,7 @@ func CompareDiff(ctx *context.APIContext) { Files: files, }) if err != nil { - ctx.ServerError("toCommit", err) + ctx.APIErrorInternal(err) return } apiCommits = append(apiCommits, apiCommit) diff --git a/routers/api/v1/repo/download.go b/routers/api/v1/repo/download.go index e6296c9fe7324..20901badfb36d 100644 --- a/routers/api/v1/repo/download.go +++ b/routers/api/v1/repo/download.go @@ -23,7 +23,7 @@ func DownloadArchive(ctx *context.APIContext) { case "bundle": tp = git.ArchiveBundle default: - ctx.Error(http.StatusBadRequest, "", fmt.Sprintf("Unknown archive type: %s", ballType)) + ctx.APIError(http.StatusBadRequest, fmt.Sprintf("Unknown archive type: %s", ballType)) return } @@ -31,20 +31,20 @@ func DownloadArchive(ctx *context.APIContext) { var err error ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository) if err != nil { - ctx.Error(http.StatusInternalServerError, "OpenRepository", err) + ctx.APIErrorInternal(err) return } } r, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*")+"."+tp.String()) if err != nil { - ctx.ServerError("NewRequest", err) + ctx.APIErrorInternal(err) return } archive, err := r.Await(ctx) if err != nil { - ctx.ServerError("archive.Await", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 045db7a291fcc..7e6a7ef087d27 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -72,7 +72,7 @@ func GetRawFile(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if ctx.Repo.Repository.IsEmpty { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -84,7 +84,7 @@ func GetRawFile(ctx *context.APIContext) { ctx.RespHeader().Set(giteaObjectTypeHeader, string(files_service.GetObjectTypeFromTreeEntry(entry))) if err := common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified); err != nil { - ctx.Error(http.StatusInternalServerError, "ServeBlob", err) + ctx.APIErrorInternal(err) } } @@ -125,7 +125,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if ctx.Repo.Repository.IsEmpty { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -145,7 +145,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) { // OK not cached - serve! if err := common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified); err != nil { - ctx.ServerError("ServeBlob", err) + ctx.APIErrorInternal(err) } return } @@ -153,7 +153,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) { // OK, now the blob is known to have at most 1024 bytes we can simply read this in one go (This saves reading it twice) dataRc, err := blob.DataAsync() if err != nil { - ctx.ServerError("DataAsync", err) + ctx.APIErrorInternal(err) return } @@ -161,7 +161,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) { buf, err := io.ReadAll(dataRc) if err != nil { _ = dataRc.Close() - ctx.ServerError("DataAsync", err) + ctx.APIErrorInternal(err) return } @@ -197,7 +197,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) { common.ServeContentByReader(ctx.Base, ctx.Repo.TreePath, blob.Size(), bytes.NewReader(buf)) return } else if err != nil { - ctx.ServerError("GetLFSMetaObjectByOid", err) + ctx.APIErrorInternal(err) return } @@ -217,7 +217,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) { lfsDataRc, err := lfs.ReadMetaObject(meta.Pointer) if err != nil { - ctx.ServerError("ReadMetaObject", err) + ctx.APIErrorInternal(err) return } defer lfsDataRc.Close() @@ -229,21 +229,21 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEn entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetTreeEntryByPath", err) + ctx.APIErrorInternal(err) } return nil, nil, nil } if entry.IsDir() || entry.IsSubModule() { - ctx.NotFound("getBlobForEntry", nil) + ctx.APIErrorNotFound("getBlobForEntry", nil) return nil, nil, nil } latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetTreePathLatestCommit", err) + ctx.APIErrorInternal(err) return nil, nil, nil } when := &latestCommit.Committer.When @@ -284,7 +284,7 @@ func GetArchive(ctx *context.APIContext) { var err error ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository) if err != nil { - ctx.Error(http.StatusInternalServerError, "OpenRepository", err) + ctx.APIErrorInternal(err) return } } @@ -296,18 +296,18 @@ func archiveDownload(ctx *context.APIContext) { aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*")) if err != nil { if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) { - ctx.Error(http.StatusBadRequest, "unknown archive format", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, archiver_service.RepoRefNotFoundError{}) { - ctx.Error(http.StatusNotFound, "unrecognized reference", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.ServerError("archiver_service.NewRequest", err) + ctx.APIErrorInternal(err) } return } archiver, err := aReq.Await(ctx) if err != nil { - ctx.ServerError("archiver.Await", err) + ctx.APIErrorInternal(err) return } @@ -339,7 +339,7 @@ func download(ctx *context.APIContext, archiveName string, archiver *repo_model. // If we have matched and access to release or issue fr, err := storage.RepoArchives.Open(rPath) if err != nil { - ctx.ServerError("Open", err) + ctx.APIErrorInternal(err) return } defer fr.Close() @@ -387,9 +387,9 @@ func GetEditorconfig(ctx *context.APIContext) { ec, _, err := ctx.Repo.GetEditorconfig(ctx.Repo.Commit) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetEditorconfig", err) + ctx.APIErrorInternal(err) } return } @@ -397,7 +397,7 @@ func GetEditorconfig(ctx *context.APIContext) { fileName := ctx.PathParam("filename") def, err := ec.GetDefinitionForFilename(fileName) if def == nil { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) return } ctx.JSON(http.StatusOK, def) @@ -470,7 +470,7 @@ func ChangeFiles(ctx *context.APIContext) { for _, file := range apiOpts.Files { contentReader, err := base64Reader(file.ContentBase64) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "Invalid base64 content", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } changeRepoFile := &files_service.ChangeRepoFile{ @@ -570,7 +570,7 @@ func CreateFile(ctx *context.APIContext) { contentReader, err := base64Reader(apiOpts.ContentBase64) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "Invalid base64 content", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } @@ -661,7 +661,7 @@ func UpdateFile(ctx *context.APIContext) { // "$ref": "#/responses/repoArchivedError" apiOpts := web.GetForm(ctx).(*api.UpdateFileOptions) if ctx.Repo.Repository.IsEmpty { - ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty")) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("repo is empty")) return } @@ -671,7 +671,7 @@ func UpdateFile(ctx *context.APIContext) { contentReader, err := base64Reader(apiOpts.ContentBase64) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "Invalid base64 content", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } @@ -723,20 +723,20 @@ func UpdateFile(ctx *context.APIContext) { func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) { if files_service.IsErrUserCannotCommit(err) || pull_service.IsErrFilePathProtected(err) { - ctx.Error(http.StatusForbidden, "Access", err) + ctx.APIError(http.StatusForbidden, err) return } if git_model.IsErrBranchAlreadyExists(err) || files_service.IsErrFilenameInvalid(err) || pull_service.IsErrSHADoesNotMatch(err) || files_service.IsErrFilePathInvalid(err) || files_service.IsErrRepoFileAlreadyExists(err) { - ctx.Error(http.StatusUnprocessableEntity, "Invalid", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } if git_model.IsErrBranchNotExist(err) || git.IsErrBranchNotExist(err) { - ctx.Error(http.StatusNotFound, "BranchDoesNotExist", err) + ctx.APIError(http.StatusNotFound, err) return } - ctx.Error(http.StatusInternalServerError, "UpdateFile", err) + ctx.APIErrorInternal(err) } // Called from both CreateFile or UpdateFile to handle both @@ -825,7 +825,7 @@ func DeleteFile(ctx *context.APIContext) { apiOpts := web.GetForm(ctx).(*api.DeleteFileOptions) if !canWriteFiles(ctx, apiOpts.BranchName) { - ctx.Error(http.StatusForbidden, "DeleteFile", repo_model.ErrUserDoesNotHaveAccessToRepo{ + ctx.APIError(http.StatusForbidden, repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, }) @@ -874,20 +874,20 @@ func DeleteFile(ctx *context.APIContext) { if filesResponse, err := files_service.ChangeRepoFiles(ctx, ctx.Repo.Repository, ctx.Doer, opts); err != nil { if git.IsErrBranchNotExist(err) || files_service.IsErrRepoFileDoesNotExist(err) || git.IsErrNotExist(err) { - ctx.Error(http.StatusNotFound, "DeleteFile", err) + ctx.APIError(http.StatusNotFound, err) return } else if git_model.IsErrBranchAlreadyExists(err) || files_service.IsErrFilenameInvalid(err) || pull_service.IsErrSHADoesNotMatch(err) || files_service.IsErrCommitIDDoesNotMatch(err) || files_service.IsErrSHAOrCommitIDNotProvided(err) { - ctx.Error(http.StatusBadRequest, "DeleteFile", err) + ctx.APIError(http.StatusBadRequest, err) return } else if files_service.IsErrUserCannotCommit(err) { - ctx.Error(http.StatusForbidden, "DeleteFile", err) + ctx.APIError(http.StatusForbidden, err) return } - ctx.Error(http.StatusInternalServerError, "DeleteFile", err) + ctx.APIErrorInternal(err) } else { fileResponse := files_service.GetFileResponseFromFilesResponse(filesResponse, 0) ctx.JSON(http.StatusOK, fileResponse) // FIXME on APIv2: return http.StatusNoContent @@ -929,7 +929,7 @@ func GetContents(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !canReadFiles(ctx.Repo) { - ctx.Error(http.StatusInternalServerError, "GetContentsOrList", repo_model.ErrUserDoesNotHaveAccessToRepo{ + ctx.APIErrorInternal(repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, }) @@ -941,10 +941,10 @@ func GetContents(ctx *context.APIContext) { if fileList, err := files_service.GetContentsOrList(ctx, ctx.Repo.Repository, treePath, ref); err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("GetContentsOrList", err) + ctx.APIErrorNotFound("GetContentsOrList", err) return } - ctx.Error(http.StatusInternalServerError, "GetContentsOrList", err) + ctx.APIErrorInternal(err) } else { ctx.JSON(http.StatusOK, fileList) } diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index f96c432b92988..58f66954e1251 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -57,15 +57,15 @@ func ListForks(ctx *context.APIContext) { forks, total, err := repo_service.FindForks(ctx, ctx.Repo.Repository, ctx.Doer, utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindForks", err) + ctx.APIErrorInternal(err) return } if err := repo_model.RepositoryList(forks).LoadOwners(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadOwners", err) + ctx.APIErrorInternal(err) return } if err := repo_model.RepositoryList(forks).LoadUnits(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadUnits", err) + ctx.APIErrorInternal(err) return } @@ -73,7 +73,7 @@ func ListForks(ctx *context.APIContext) { for i, fork := range forks { permission, err := access_model.GetUserRepoPermission(ctx, fork, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return } apiForks[i] = convert.ToRepo(ctx, fork, permission) @@ -126,19 +126,19 @@ func CreateFork(ctx *context.APIContext) { org, err := organization.GetOrgByName(ctx, *form.Organization) if err != nil { if organization.IsErrOrgNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "GetOrgByName", err) + ctx.APIErrorInternal(err) } return } if !ctx.Doer.IsAdmin { isMember, err := org.IsOrgMember(ctx, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrgMember", err) + ctx.APIErrorInternal(err) return } else if !isMember { - ctx.Error(http.StatusForbidden, "isMemberNot", fmt.Sprintf("User is no Member of Organisation '%s'", org.Name)) + ctx.APIError(http.StatusForbidden, fmt.Sprintf("User is no Member of Organisation '%s'", org.Name)) return } } @@ -159,11 +159,11 @@ func CreateFork(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrAlreadyExist) || repo_model.IsErrReachLimitOfRepo(err) { - ctx.Error(http.StatusConflict, "ForkRepository", err) + ctx.APIError(http.StatusConflict, err) } else if errors.Is(err, user_model.ErrBlockedUser) { - ctx.Error(http.StatusForbidden, "ForkRepository", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "ForkRepository", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/repo/git_hook.go b/routers/api/v1/repo/git_hook.go index 868acf3d853ba..487c74e183cc9 100644 --- a/routers/api/v1/repo/git_hook.go +++ b/routers/api/v1/repo/git_hook.go @@ -40,7 +40,7 @@ func ListGitHooks(ctx *context.APIContext) { hooks, err := ctx.Repo.GitRepo.Hooks() if err != nil { - ctx.Error(http.StatusInternalServerError, "Hooks", err) + ctx.APIErrorInternal(err) return } @@ -84,9 +84,9 @@ func GetGitHook(ctx *context.APIContext) { hook, err := ctx.Repo.GitRepo.GetHook(hookID) if err != nil { if errors.Is(err, git.ErrNotValidHook) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetHook", err) + ctx.APIErrorInternal(err) } return } @@ -131,16 +131,16 @@ func EditGitHook(ctx *context.APIContext) { hook, err := ctx.Repo.GitRepo.GetHook(hookID) if err != nil { if errors.Is(err, git.ErrNotValidHook) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetHook", err) + ctx.APIErrorInternal(err) } return } hook.Content = form.Content if err = hook.Update(); err != nil { - ctx.Error(http.StatusInternalServerError, "hook.Update", err) + ctx.APIErrorInternal(err) return } @@ -180,16 +180,16 @@ func DeleteGitHook(ctx *context.APIContext) { hook, err := ctx.Repo.GitRepo.GetHook(hookID) if err != nil { if errors.Is(err, git.ErrNotValidHook) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetHook", err) + ctx.APIErrorInternal(err) } return } hook.Content = "" if err = hook.Update(); err != nil { - ctx.Error(http.StatusInternalServerError, "hook.Update", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/git_ref.go b/routers/api/v1/repo/git_ref.go index 1743c0fc20d1d..f042e9e344b6f 100644 --- a/routers/api/v1/repo/git_ref.go +++ b/routers/api/v1/repo/git_ref.go @@ -4,6 +4,7 @@ package repo import ( + "fmt" "net/http" "net/url" @@ -77,12 +78,12 @@ func GetGitRefs(ctx *context.APIContext) { func getGitRefsInternal(ctx *context.APIContext, filter string) { refs, lastMethodName, err := utils.GetGitRefs(ctx, filter) if err != nil { - ctx.Error(http.StatusInternalServerError, lastMethodName, err) + ctx.APIErrorInternal(fmt.Errorf("%s: %w", lastMethodName, err)) return } if len(refs) == 0 { - ctx.NotFound() + ctx.APIErrorNotFound() return } diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go index 03143c8f99e2e..ac47e15d645c3 100644 --- a/routers/api/v1/repo/hook.go +++ b/routers/api/v1/repo/hook.go @@ -61,7 +61,7 @@ func ListHooks(ctx *context.APIContext) { hooks, count, err := db.FindAndCount[webhook.Webhook](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -69,7 +69,7 @@ func ListHooks(ctx *context.APIContext) { for i := range hooks { apiHooks[i], err = webhook_service.ToHook(ctx.Repo.RepoLink, hooks[i]) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } } @@ -116,7 +116,7 @@ func GetHook(ctx *context.APIContext) { } apiHook, err := webhook_service.ToHook(repo.RepoLink, hook) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, apiHook) @@ -189,7 +189,7 @@ func TestHook(ctx *context.APIContext) { Pusher: convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone), Sender: convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone), }); err != nil { - ctx.Error(http.StatusInternalServerError, "PrepareWebhook: ", err) + ctx.APIErrorInternal(err) return } @@ -298,9 +298,9 @@ func DeleteHook(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if err := webhook.DeleteWebhookByRepoID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("id")); err != nil { if webhook.IsErrWebhookNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "DeleteWebhookByRepoID", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 86dbcee5f7de6..c9575ff98a001 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -132,7 +132,7 @@ func SearchIssues(ctx *context.APIContext) { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } @@ -170,9 +170,9 @@ func SearchIssues(ctx *context.APIContext) { owner, err := user_model.GetUserByName(ctx, ctx.FormString("owner")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusBadRequest, "Owner not found", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return } @@ -183,15 +183,15 @@ func SearchIssues(ctx *context.APIContext) { } if ctx.FormString("team") != "" { if ctx.FormString("owner") == "" { - ctx.Error(http.StatusBadRequest, "", "Owner organisation is required for filtering on team") + ctx.APIError(http.StatusBadRequest, "Owner organisation is required for filtering on team") return } team, err := organization.GetTeam(ctx, opts.OwnerID, ctx.FormString("team")) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusBadRequest, "Team not found", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return } @@ -204,7 +204,7 @@ func SearchIssues(ctx *context.APIContext) { } repoIDs, _, err = repo_model.SearchRepositoryIDs(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchRepositoryIDs", err) + ctx.APIErrorInternal(err) return } if len(repoIDs) == 0 { @@ -237,7 +237,7 @@ func SearchIssues(ctx *context.APIContext) { } includedAnyLabels, err = issues_model.GetLabelIDsByNames(ctx, includedLabelNames) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelIDsByNames", err) + ctx.APIErrorInternal(err) return } } @@ -251,7 +251,7 @@ func SearchIssues(ctx *context.APIContext) { } includedMilestones, err = issues_model.GetMilestoneIDsByNames(ctx, includedMilestoneNames) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetMilestoneIDsByNames", err) + ctx.APIErrorInternal(err) return } } @@ -312,12 +312,12 @@ func SearchIssues(ctx *context.APIContext) { ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchIssues", err) + ctx.APIErrorInternal(err) return } issues, err := issues_model.GetIssuesByIDs(ctx, ids, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindIssuesByIDs", err) + ctx.APIErrorInternal(err) return } @@ -405,7 +405,7 @@ func ListIssues(ctx *context.APIContext) { // "$ref": "#/responses/notFound" before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } @@ -428,7 +428,7 @@ func ListIssues(ctx *context.APIContext) { if splitted := strings.Split(ctx.FormString("labels"), ","); len(splitted) > 0 { labelIDs, err = issues_model.GetLabelIDsInRepoByNames(ctx, ctx.Repo.Repository.ID, splitted) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err) + ctx.APIErrorInternal(err) return } } @@ -444,7 +444,7 @@ func ListIssues(ctx *context.APIContext) { continue } if !issues_model.IsErrMilestoneNotExist(err) { - ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoIDANDName", err) + ctx.APIErrorInternal(err) return } id, err := strconv.ParseInt(part[i], 10, 64) @@ -459,7 +459,7 @@ func ListIssues(ctx *context.APIContext) { if issues_model.IsErrMilestoneNotExist(err) { continue } - ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err) + ctx.APIErrorInternal(err) } } @@ -474,7 +474,7 @@ func ListIssues(ctx *context.APIContext) { } if isPull.Has() && !ctx.Repo.CanReadIssuesOrPulls(isPull.Value()) { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -482,7 +482,7 @@ func ListIssues(ctx *context.APIContext) { canReadIssues := ctx.Repo.CanRead(unit.TypeIssues) canReadPulls := ctx.Repo.CanRead(unit.TypePullRequests) if !canReadIssues && !canReadPulls { - ctx.NotFound() + ctx.APIErrorNotFound() return } else if !canReadIssues { isPull = optional.Some(true) @@ -549,12 +549,12 @@ func ListIssues(ctx *context.APIContext) { ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchIssues", err) + ctx.APIErrorInternal(err) return } issues, err := issues_model.GetIssuesByIDs(ctx, ids, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindIssuesByIDs", err) + ctx.APIErrorInternal(err) return } @@ -571,12 +571,12 @@ func getUserIDForFilter(ctx *context.APIContext, queryName string) int64 { user, err := user_model.GetUserByName(ctx, userName) if user_model.IsErrUserNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) return 0 } if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return 0 } @@ -616,14 +616,14 @@ func GetIssue(ctx *context.APIContext) { issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) { - ctx.NotFound() + ctx.APIErrorNotFound() return } ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, ctx.Doer, issue)) @@ -691,9 +691,9 @@ func CreateIssue(ctx *context.APIContext) { assigneeIDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(ctx, form.Assignee, form.Assignees) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Assignee does not exist: [name: %s]", err)) } else { - ctx.Error(http.StatusInternalServerError, "AddAssigneeByName", err) + ctx.APIErrorInternal(err) } return } @@ -702,17 +702,17 @@ func CreateIssue(ctx *context.APIContext) { for _, aID := range assigneeIDs { assignee, err := user_model.GetUserByID(ctx, aID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserByID", err) + ctx.APIErrorInternal(err) return } valid, err := access_model.CanBeAssigned(ctx, assignee, ctx.Repo.Repository, false) if err != nil { - ctx.Error(http.StatusInternalServerError, "canBeAssigned", err) + ctx.APIErrorInternal(err) return } if !valid { - ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name}) + ctx.APIError(http.StatusUnprocessableEntity, repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name}) return } } @@ -723,11 +723,11 @@ func CreateIssue(ctx *context.APIContext) { if err := issue_service.NewIssue(ctx, ctx.Repo.Repository, issue, form.Labels, nil, assigneeIDs, 0); err != nil { if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { - ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, user_model.ErrBlockedUser) { - ctx.Error(http.StatusForbidden, "NewIssue", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "NewIssue", err) + ctx.APIErrorInternal(err) } return } @@ -735,10 +735,10 @@ func CreateIssue(ctx *context.APIContext) { if form.Closed { if err := issue_service.CloseIssue(ctx, issue, ctx.Doer, ""); err != nil { if issues_model.IsErrDependenciesLeft(err) { - ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies") + ctx.APIError(http.StatusPreconditionFailed, "cannot close this issue because it still has open dependencies") return } - ctx.Error(http.StatusInternalServerError, "ChangeStatus", err) + ctx.APIErrorInternal(err) return } } @@ -746,7 +746,7 @@ func CreateIssue(ctx *context.APIContext) { // Refetch from database to assign some automatic values issue, err = issues_model.GetIssueByID(ctx, issue.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetIssueByID", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, issue)) @@ -796,9 +796,9 @@ func EditIssue(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -807,7 +807,7 @@ func EditIssue(ctx *context.APIContext) { err = issue.LoadAttributes(ctx) if err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } @@ -819,7 +819,7 @@ func EditIssue(ctx *context.APIContext) { if len(form.Title) > 0 { err = issue_service.ChangeTitle(ctx, issue, ctx.Doer, form.Title) if err != nil { - ctx.Error(http.StatusInternalServerError, "ChangeTitle", err) + ctx.APIErrorInternal(err) return } } @@ -827,18 +827,18 @@ func EditIssue(ctx *context.APIContext) { err = issue_service.ChangeContent(ctx, issue, ctx.Doer, *form.Body, issue.ContentVersion) if err != nil { if errors.Is(err, issues_model.ErrIssueAlreadyChanged) { - ctx.Error(http.StatusBadRequest, "ChangeContent", err) + ctx.APIError(http.StatusBadRequest, err) return } - ctx.Error(http.StatusInternalServerError, "ChangeContent", err) + ctx.APIErrorInternal(err) return } } if form.Ref != nil { err = issue_service.ChangeIssueRef(ctx, issue, ctx.Doer, *form.Ref) if err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateRef", err) + ctx.APIErrorInternal(err) return } } @@ -849,7 +849,7 @@ func EditIssue(ctx *context.APIContext) { if form.RemoveDeadline == nil || !*form.RemoveDeadline { if form.Deadline == nil { - ctx.Error(http.StatusBadRequest, "", "The due_date cannot be empty") + ctx.APIError(http.StatusBadRequest, "The due_date cannot be empty") return } if !form.Deadline.IsZero() { @@ -860,7 +860,7 @@ func EditIssue(ctx *context.APIContext) { } if err := issues_model.UpdateIssueDeadline(ctx, issue, deadlineUnix, ctx.Doer); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) + ctx.APIErrorInternal(err) return } issue.DeadlineUnix = deadlineUnix @@ -883,9 +883,9 @@ 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.Error(http.StatusForbidden, "UpdateAssignees", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "UpdateAssignees", err) + ctx.APIErrorInternal(err) } return } @@ -896,18 +896,18 @@ func EditIssue(ctx *context.APIContext) { oldMilestoneID := issue.MilestoneID issue.MilestoneID = *form.Milestone if err = issue_service.ChangeMilestoneAssign(ctx, issue, ctx.Doer, oldMilestoneID); err != nil { - ctx.Error(http.StatusInternalServerError, "ChangeMilestoneAssign", err) + ctx.APIErrorInternal(err) return } } if form.State != nil { if issue.IsPull { if err := issue.LoadPullRequest(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "GetPullRequest", err) + ctx.APIErrorInternal(err) return } if issue.PullRequest.HasMerged { - ctx.Error(http.StatusPreconditionFailed, "MergedPRState", "cannot change state of this pull request, it was already merged") + ctx.APIError(http.StatusPreconditionFailed, "cannot change state of this pull request, it was already merged") return } } @@ -922,11 +922,11 @@ func EditIssue(ctx *context.APIContext) { // Refetch from database to assign some automatic values issue, err = issues_model.GetIssueByID(ctx, issue.ID) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if err = issue.LoadMilestone(ctx); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusCreated, convert.ToAPIIssue(ctx, ctx.Doer, issue)) @@ -963,15 +963,15 @@ func DeleteIssue(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByID", err) + ctx.APIErrorInternal(err) } return } if err = issue_service.DeleteIssue(ctx, ctx.Doer, ctx.Repo.GitRepo, issue); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteIssueByID", err) + ctx.APIErrorInternal(err) return } @@ -1019,21 +1019,21 @@ func UpdateIssueDeadline(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.Error(http.StatusForbidden, "", "Not repo writer") + ctx.APIError(http.StatusForbidden, "Not repo writer") return } deadlineUnix, _ := common.ParseAPIDeadlineToEndOfDay(form.Deadline) if err := issues_model.UpdateIssueDeadline(ctx, issue, deadlineUnix, ctx.Doer); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) + ctx.APIErrorInternal(err) return } @@ -1042,22 +1042,22 @@ func UpdateIssueDeadline(ctx *context.APIContext) { func closeOrReopenIssue(ctx *context.APIContext, issue *issues_model.Issue, state api.StateType) { if state != api.StateOpen && state != api.StateClosed { - ctx.Error(http.StatusPreconditionFailed, "UnknownIssueStateError", fmt.Sprintf("unknown state: %s", state)) + ctx.APIError(http.StatusPreconditionFailed, fmt.Sprintf("unknown state: %s", state)) return } if state == api.StateClosed && !issue.IsClosed { if err := issue_service.CloseIssue(ctx, issue, ctx.Doer, ""); err != nil { if issues_model.IsErrDependenciesLeft(err) { - ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue or pull request because it still has open dependencies") + ctx.APIError(http.StatusPreconditionFailed, "cannot close this issue or pull request because it still has open dependencies") return } - ctx.Error(http.StatusInternalServerError, "CloseIssue", err) + ctx.APIErrorInternal(err) return } } else if state == api.StateOpen && issue.IsClosed { if err := issue_service.ReopenIssue(ctx, issue, ctx.Doer, ""); err != nil { - ctx.Error(http.StatusInternalServerError, "ReopenIssue", err) + ctx.APIErrorInternal(err) return } } diff --git a/routers/api/v1/repo/issue_attachment.go b/routers/api/v1/repo/issue_attachment.go index d0bcadde372b2..3f751a295c37e 100644 --- a/routers/api/v1/repo/issue_attachment.go +++ b/routers/api/v1/repo/issue_attachment.go @@ -104,7 +104,7 @@ func ListIssueAttachments(ctx *context.APIContext) { } if err := issue.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } @@ -171,7 +171,7 @@ func CreateIssueAttachment(ctx *context.APIContext) { // Get uploaded file from request file, header, err := ctx.Req.FormFile("attachment") if err != nil { - ctx.Error(http.StatusInternalServerError, "FormFile", err) + ctx.APIErrorInternal(err) return } defer file.Close() @@ -189,9 +189,9 @@ func CreateIssueAttachment(ctx *context.APIContext) { }) if err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "UploadAttachment", err) + ctx.APIErrorInternal(err) } return } @@ -199,7 +199,7 @@ func CreateIssueAttachment(ctx *context.APIContext) { issue.Attachments = append(issue.Attachments, attachment) if err := issue_service.ChangeContent(ctx, issue, ctx.Doer, issue.Content, issue.ContentVersion); err != nil { - ctx.Error(http.StatusInternalServerError, "ChangeContent", err) + ctx.APIErrorInternal(err) return } @@ -265,10 +265,10 @@ func EditIssueAttachment(ctx *context.APIContext) { if err := attachment_service.UpdateAttachment(ctx, setting.Attachment.AllowedTypes, attachment); err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "UpdateAttachment", err) + ctx.APIErrorInternal(err) return } @@ -319,7 +319,7 @@ func DeleteIssueAttachment(ctx *context.APIContext) { } if err := repo_model.DeleteAttachment(ctx, attachment, true); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteAttachment", err) + ctx.APIErrorInternal(err) return } @@ -329,7 +329,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("GetIssueByIndex", issues_model.IsErrIssueNotExist, err) + ctx.NotFoundOrServerError(err) return nil } @@ -354,7 +354,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("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err) + ctx.NotFoundOrServerError(err) return nil } if !attachmentBelongsToRepoOrIssue(ctx, attachment, issue) { @@ -366,7 +366,7 @@ func getIssueAttachmentSafeRead(ctx *context.APIContext, issue *issues_model.Iss func canUserWriteIssueAttachment(ctx *context.APIContext, issue *issues_model.Issue) bool { canEditIssue := ctx.IsSigned && (ctx.Doer.ID == issue.PosterID || ctx.IsUserRepoAdmin() || ctx.IsUserSiteAdmin() || ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) if !canEditIssue { - ctx.Error(http.StatusForbidden, "", "user should have permission to write issue") + ctx.APIError(http.StatusForbidden, "user should have permission to write issue") return false } @@ -376,16 +376,16 @@ func canUserWriteIssueAttachment(ctx *context.APIContext, issue *issues_model.Is func attachmentBelongsToRepoOrIssue(ctx *context.APIContext, attachment *repo_model.Attachment, issue *issues_model.Issue) bool { if attachment.RepoID != ctx.Repo.Repository.ID { log.Debug("Requested attachment[%d] does not belong to repo[%-v].", attachment.ID, ctx.Repo.Repository) - ctx.NotFound("no such attachment in repo") + ctx.APIErrorNotFound("no such attachment in repo") return false } if attachment.IssueID == 0 { log.Debug("Requested attachment[%d] is not in an issue.", attachment.ID) - ctx.NotFound("no such attachment in issue") + ctx.APIErrorNotFound("no such attachment in issue") return false } else if issue != nil && attachment.IssueID != issue.ID { log.Debug("Requested attachment[%d] does not belong to issue[%d, #%d].", attachment.ID, issue.ID, issue.Index) - ctx.NotFound("no such attachment in issue") + ctx.APIErrorNotFound("no such attachment in issue") return false } return true diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 96a61a527e93b..0c572a06a8273 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -65,16 +65,16 @@ func ListIssueComments(ctx *context.APIContext) { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err) + ctx.APIErrorInternal(err) return } if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -89,23 +89,23 @@ func ListIssueComments(ctx *context.APIContext) { comments, err := issues_model.FindComments(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindComments", err) + ctx.APIErrorInternal(err) return } totalCount, err := issues_model.CountComments(ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if err := comments.LoadPosters(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadPosters", err) + ctx.APIErrorInternal(err) return } if err := comments.LoadAttachments(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttachments", err) + ctx.APIErrorInternal(err) return } @@ -169,12 +169,12 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err) + ctx.APIErrorInternal(err) return } issue.Repo = ctx.Repo.Repository @@ -189,12 +189,12 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) { comments, err := issues_model.FindComments(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindComments", err) + ctx.APIErrorInternal(err) return } if err := comments.LoadPosters(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadPosters", err) + ctx.APIErrorInternal(err) return } @@ -274,7 +274,7 @@ func ListRepoIssueComments(ctx *context.APIContext) { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } @@ -288,7 +288,7 @@ func ListRepoIssueComments(ctx *context.APIContext) { } else if canReadPull { isPull = optional.Some(true) } else { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -303,32 +303,32 @@ func ListRepoIssueComments(ctx *context.APIContext) { comments, err := issues_model.FindComments(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindComments", err) + ctx.APIErrorInternal(err) return } totalCount, err := issues_model.CountComments(ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if err = comments.LoadPosters(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadPosters", err) + ctx.APIErrorInternal(err) return } apiComments := make([]*api.Comment, len(comments)) if err := comments.LoadIssues(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadIssues", err) + ctx.APIErrorInternal(err) return } if err := comments.LoadAttachments(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttachments", err) + ctx.APIErrorInternal(err) return } if _, err := comments.Issues().LoadRepositories(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadRepositories", err) + ctx.APIErrorInternal(err) return } for i := range comments { @@ -382,26 +382,26 @@ func CreateIssueComment(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.CreateIssueCommentOption) issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) return } if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) { - ctx.NotFound() + ctx.APIErrorNotFound() return } if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin { - ctx.Error(http.StatusForbidden, "CreateIssueComment", errors.New(ctx.Locale.TrString("repo.issues.comment_on_locked"))) + ctx.APIError(http.StatusForbidden, errors.New(ctx.Locale.TrString("repo.issues.comment_on_locked"))) return } comment, err := issue_service.CreateIssueComment(ctx, ctx.Doer, ctx.Repo.Repository, issue, form.Body, nil) if err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.Error(http.StatusForbidden, "CreateIssueComment", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateIssueComment", err) + ctx.APIErrorInternal(err) } return } @@ -448,15 +448,15 @@ func GetIssueComment(ctx *context.APIContext) { comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrCommentNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) + ctx.APIErrorInternal(err) } return } if err = comment.LoadIssue(ctx); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if comment.Issue.RepoID != ctx.Repo.Repository.ID { @@ -465,7 +465,7 @@ func GetIssueComment(ctx *context.APIContext) { } if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -475,7 +475,7 @@ func GetIssueComment(ctx *context.APIContext) { } if err := comment.LoadPoster(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "comment.LoadPoster", err) + ctx.APIErrorInternal(err) return } @@ -582,15 +582,15 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrCommentNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) + ctx.APIErrorInternal(err) } return } if err := comment.LoadIssue(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadIssue", err) + ctx.APIErrorInternal(err) return } @@ -613,9 +613,9 @@ 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.Error(http.StatusForbidden, "UpdateComment", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "UpdateComment", err) + ctx.APIErrorInternal(err) } return } @@ -699,15 +699,15 @@ func deleteIssueComment(ctx *context.APIContext) { comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrCommentNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) + ctx.APIErrorInternal(err) } return } if err := comment.LoadIssue(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadIssue", err) + ctx.APIErrorInternal(err) return } @@ -725,7 +725,7 @@ func deleteIssueComment(ctx *context.APIContext) { } if err = issue_service.DeleteComment(ctx, ctx.Doer, comment); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteCommentByID", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/issue_comment_attachment.go b/routers/api/v1/repo/issue_comment_attachment.go index a556a803e51bb..5f660c57504dd 100644 --- a/routers/api/v1/repo/issue_comment_attachment.go +++ b/routers/api/v1/repo/issue_comment_attachment.go @@ -67,7 +67,7 @@ func GetIssueCommentAttachment(ctx *context.APIContext) { } if attachment.CommentID != comment.ID { log.Debug("User requested attachment[%d] is not in comment[%d].", attachment.ID, comment.ID) - ctx.NotFound("attachment not in comment") + ctx.APIErrorNotFound("attachment not in comment") return } @@ -109,7 +109,7 @@ func ListIssueCommentAttachments(ctx *context.APIContext) { } if err := comment.LoadAttachments(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttachments", err) + ctx.APIErrorInternal(err) return } @@ -179,7 +179,7 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) { // Get uploaded file from request file, header, err := ctx.Req.FormFile("attachment") if err != nil { - ctx.Error(http.StatusInternalServerError, "FormFile", err) + ctx.APIErrorInternal(err) return } defer file.Close() @@ -198,23 +198,23 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) { }) if err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "UploadAttachment", err) + ctx.APIErrorInternal(err) } return } if err := comment.LoadAttachments(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttachments", err) + ctx.APIErrorInternal(err) return } if err = issue_service.UpdateComment(ctx, comment, comment.ContentVersion, ctx.Doer, comment.Content); err != nil { if errors.Is(err, user_model.ErrBlockedUser) { - ctx.Error(http.StatusForbidden, "UpdateComment", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.ServerError("UpdateComment", err) + ctx.APIErrorInternal(err) } return } @@ -279,10 +279,10 @@ func EditIssueCommentAttachment(ctx *context.APIContext) { if err := attachment_service.UpdateAttachment(ctx, setting.Attachment.AllowedTypes, attach); err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attach)) @@ -331,7 +331,7 @@ func DeleteIssueCommentAttachment(ctx *context.APIContext) { } if err := repo_model.DeleteAttachment(ctx, attach, true); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteAttachment", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -340,15 +340,15 @@ 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("GetCommentByID", issues_model.IsErrCommentNotExist, err) + ctx.NotFoundOrServerError(err) return nil } if err := comment.LoadIssue(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "comment.LoadIssue", err) + ctx.APIErrorInternal(err) return nil } if comment.Issue == nil || comment.Issue.RepoID != ctx.Repo.Repository.ID { - ctx.Error(http.StatusNotFound, "", "no matching issue comment found") + ctx.APIError(http.StatusNotFound, "no matching issue comment found") return nil } @@ -375,7 +375,7 @@ func getIssueCommentAttachmentSafeWrite(ctx *context.APIContext) *repo_model.Att func canUserWriteIssueCommentAttachment(ctx *context.APIContext, comment *issues_model.Comment) bool { canEditComment := ctx.IsSigned && (ctx.Doer.ID == comment.PosterID || ctx.IsUserRepoAdmin() || ctx.IsUserSiteAdmin()) && ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull) if !canEditComment { - ctx.Error(http.StatusForbidden, "", "user should have permission to edit comment") + ctx.APIError(http.StatusForbidden, "user should have permission to edit comment") return false } @@ -385,7 +385,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("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err) + ctx.NotFoundOrServerError(err) return nil } if !attachmentBelongsToRepoOrComment(ctx, attachment, comment) { @@ -397,17 +397,17 @@ func getIssueCommentAttachmentSafeRead(ctx *context.APIContext, comment *issues_ func attachmentBelongsToRepoOrComment(ctx *context.APIContext, attachment *repo_model.Attachment, comment *issues_model.Comment) bool { if attachment.RepoID != ctx.Repo.Repository.ID { log.Debug("Requested attachment[%d] does not belong to repo[%-v].", attachment.ID, ctx.Repo.Repository) - ctx.NotFound("no such attachment in repo") + ctx.APIErrorNotFound("no such attachment in repo") return false } if attachment.IssueID == 0 || attachment.CommentID == 0 { log.Debug("Requested attachment[%d] is not in a comment.", attachment.ID) - ctx.NotFound("no such attachment in comment") + ctx.APIErrorNotFound("no such attachment in comment") return false } if comment != nil && attachment.CommentID != comment.ID { log.Debug("Requested attachment[%d] does not belong to comment[%d].", attachment.ID, comment.ID) - ctx.NotFound("no such attachment in comment") + ctx.APIErrorNotFound("no such attachment in comment") return false } return true diff --git a/routers/api/v1/repo/issue_dependency.go b/routers/api/v1/repo/issue_dependency.go index 19dcf999b804b..2048c76ea0ef5 100644 --- a/routers/api/v1/repo/issue_dependency.go +++ b/routers/api/v1/repo/issue_dependency.go @@ -57,23 +57,23 @@ func GetIssueDependencies(ctx *context.APIContext) { // If this issue's repository does not enable dependencies then there can be no dependencies by default if !ctx.Repo.Repository.IsDependenciesEnabled(ctx) { - ctx.NotFound() + ctx.APIErrorNotFound() return } issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound("IsErrIssueNotExist", err) + ctx.APIErrorNotFound("IsErrIssueNotExist", err) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } // 1. We must be able to read this issue if !ctx.Repo.Permission.CanReadIssuesOrPulls(issue.IsPull) { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -98,7 +98,7 @@ func GetIssueDependencies(ctx *context.APIContext) { PageSize: limit, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "BlockedByDependencies", err) + ctx.APIErrorInternal(err) return } @@ -116,7 +116,7 @@ func GetIssueDependencies(ctx *context.APIContext) { var err error perm, err = access_model.GetUserRepoPermission(ctx, &blocker.Repository, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return } repoPerms[blocker.RepoID] = perm @@ -324,7 +324,7 @@ func GetIssueBlocks(ctx *context.APIContext) { } if !ctx.Repo.Permission.CanReadIssuesOrPulls(issue.IsPull) { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -342,7 +342,7 @@ func GetIssueBlocks(ctx *context.APIContext) { deps, err := issue.BlockingDependencies(ctx) if err != nil { - ctx.Error(http.StatusInternalServerError, "BlockingDependencies", err) + ctx.APIErrorInternal(err) return } @@ -367,7 +367,7 @@ func GetIssueBlocks(ctx *context.APIContext) { var err error perm, err = access_model.GetUserRepoPermission(ctx, &depMeta.Repository, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return } repoPerms[depMeta.RepoID] = perm @@ -502,9 +502,9 @@ func getParamsIssue(ctx *context.APIContext) *issues_model.Issue { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound("IsErrIssueNotExist", err) + ctx.APIErrorNotFound("IsErrIssueNotExist", err) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return nil } @@ -523,9 +523,9 @@ func getFormIssue(ctx *context.APIContext, form *api.IssueMeta) *issues_model.Is repo, err = repo_model.GetRepositoryByOwnerAndName(ctx, form.Owner, form.Name) if err != nil { if repo_model.IsErrRepoNotExist(err) { - ctx.NotFound("IsErrRepoNotExist", err) + ctx.APIErrorNotFound("IsErrRepoNotExist", err) } else { - ctx.Error(http.StatusInternalServerError, "GetRepositoryByOwnerAndName", err) + ctx.APIErrorInternal(err) } return nil } @@ -536,9 +536,9 @@ func getFormIssue(ctx *context.APIContext, form *api.IssueMeta) *issues_model.Is issue, err := issues_model.GetIssueByIndex(ctx, repo.ID, form.Index) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound("IsErrIssueNotExist", err) + ctx.APIErrorNotFound("IsErrIssueNotExist", err) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return nil } @@ -553,7 +553,7 @@ func getPermissionForRepo(ctx *context.APIContext, repo *repo_model.Repository) perm, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return nil } @@ -563,25 +563,25 @@ func getPermissionForRepo(ctx *context.APIContext, repo *repo_model.Repository) func createIssueDependency(ctx *context.APIContext, target, dependency *issues_model.Issue, targetPerm, dependencyPerm access_model.Permission) { if target.Repo.IsArchived || !target.Repo.IsDependenciesEnabled(ctx) { // The target's repository doesn't have dependencies enabled - ctx.NotFound() + ctx.APIErrorNotFound() return } if !targetPerm.CanWriteIssuesOrPulls(target.IsPull) { // We can't write to the target - ctx.NotFound() + ctx.APIErrorNotFound() return } if !dependencyPerm.CanReadIssuesOrPulls(dependency.IsPull) { // We can't read the dependency - ctx.NotFound() + ctx.APIErrorNotFound() return } err := issues_model.CreateIssueDependency(ctx, ctx.Doer, target, dependency) if err != nil { - ctx.Error(http.StatusInternalServerError, "CreateIssueDependency", err) + ctx.APIErrorInternal(err) return } } @@ -589,25 +589,25 @@ func createIssueDependency(ctx *context.APIContext, target, dependency *issues_m func removeIssueDependency(ctx *context.APIContext, target, dependency *issues_model.Issue, targetPerm, dependencyPerm access_model.Permission) { if target.Repo.IsArchived || !target.Repo.IsDependenciesEnabled(ctx) { // The target's repository doesn't have dependencies enabled - ctx.NotFound() + ctx.APIErrorNotFound() return } if !targetPerm.CanWriteIssuesOrPulls(target.IsPull) { // We can't write to the target - ctx.NotFound() + ctx.APIErrorNotFound() return } if !dependencyPerm.CanReadIssuesOrPulls(dependency.IsPull) { // We can't read the dependency - ctx.NotFound() + ctx.APIErrorNotFound() return } err := issues_model.RemoveIssueDependency(ctx, ctx.Doer, target, dependency, issues_model.DependencyTypeBlockedBy) if err != nil { - ctx.Error(http.StatusInternalServerError, "CreateIssueDependency", err) + ctx.APIErrorInternal(err) return } } diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index ee1a842bc619d..f8e14e049064b 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -50,15 +50,15 @@ func ListIssueLabels(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } if err := issue.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } @@ -110,13 +110,13 @@ func AddIssueLabels(ctx *context.APIContext) { } if err = issue_service.AddLabels(ctx, issue, ctx.Doer, labels); err != nil { - ctx.Error(http.StatusInternalServerError, "AddLabels", err) + ctx.APIErrorInternal(err) return } labels, err = issues_model.GetLabelsByIssueID(ctx, issue.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelsByIssueID", err) + ctx.APIErrorInternal(err) return } @@ -166,9 +166,9 @@ func DeleteIssueLabel(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -181,15 +181,15 @@ func DeleteIssueLabel(ctx *context.APIContext) { label, err := issues_model.GetLabelByID(ctx, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrLabelNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "GetLabelByID", err) + ctx.APIErrorInternal(err) } return } if err := issue_service.RemoveLabel(ctx, issue, ctx.Doer, label); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteIssueLabel", err) + ctx.APIErrorInternal(err) return } @@ -240,13 +240,13 @@ func ReplaceIssueLabels(ctx *context.APIContext) { } if err := issue_service.ReplaceLabels(ctx, issue, ctx.Doer, labels); err != nil { - ctx.Error(http.StatusInternalServerError, "ReplaceLabels", err) + ctx.APIErrorInternal(err) return } labels, err = issues_model.GetLabelsByIssueID(ctx, issue.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelsByIssueID", err) + ctx.APIErrorInternal(err) return } @@ -288,9 +288,9 @@ func ClearIssueLabels(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -301,7 +301,7 @@ func ClearIssueLabels(ctx *context.APIContext) { } if err := issue_service.ClearLabels(ctx, issue, ctx.Doer); err != nil { - ctx.Error(http.StatusInternalServerError, "ClearLabels", err) + ctx.APIErrorInternal(err) return } @@ -312,15 +312,15 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return nil, nil, err } if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.Error(http.StatusForbidden, "CanWriteIssuesOrPulls", "write permission is required") + ctx.APIError(http.StatusForbidden, "write permission is required") return nil, nil, fmt.Errorf("permission denied") } @@ -336,25 +336,25 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) case reflect.String: labelNames = append(labelNames, rv.String()) default: - ctx.Error(http.StatusBadRequest, "InvalidLabel", "a label must be an integer or a string") + ctx.APIError(http.StatusBadRequest, "a label must be an integer or a string") return nil, nil, fmt.Errorf("invalid label") } } if len(labelIDs) > 0 && len(labelNames) > 0 { - ctx.Error(http.StatusBadRequest, "InvalidLabels", "labels should be an array of strings or integers") + ctx.APIError(http.StatusBadRequest, "labels should be an array of strings or integers") return nil, nil, fmt.Errorf("invalid labels") } if len(labelNames) > 0 { repoLabelIDs, err := issues_model.GetLabelIDsInRepoByNames(ctx, ctx.Repo.Repository.ID, labelNames) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err) + ctx.APIErrorInternal(err) return nil, nil, err } labelIDs = append(labelIDs, repoLabelIDs...) if ctx.Repo.Owner.IsOrganization() { orgLabelIDs, err := issues_model.GetLabelIDsInOrgByNames(ctx, ctx.Repo.Owner.ID, labelNames) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelIDsInOrgByNames", err) + ctx.APIErrorInternal(err) return nil, nil, err } labelIDs = append(labelIDs, orgLabelIDs...) @@ -363,7 +363,7 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) labels, err := issues_model.GetLabelsByIDs(ctx, labelIDs, "id", "repo_id", "org_id", "name", "exclusive") if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelsByIDs", err) + ctx.APIErrorInternal(err) return nil, nil, err } diff --git a/routers/api/v1/repo/issue_pin.go b/routers/api/v1/repo/issue_pin.go index 388d4a3e99baa..71985ac765797 100644 --- a/routers/api/v1/repo/issue_pin.go +++ b/routers/api/v1/repo/issue_pin.go @@ -44,11 +44,11 @@ func PinIssue(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else if issues_model.IsErrIssueMaxPinReached(err) { - ctx.Error(http.StatusBadRequest, "MaxPinReached", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -56,13 +56,13 @@ func PinIssue(ctx *context.APIContext) { // If we don't do this, it will crash when trying to add the pin event to the comment history err = issue.LoadRepo(ctx) if err != nil { - ctx.Error(http.StatusInternalServerError, "LoadRepo", err) + ctx.APIErrorInternal(err) return } - err = issue.Pin(ctx, ctx.Doer) + err = issues_model.PinIssue(ctx, issue, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "PinIssue", err) + ctx.APIErrorInternal(err) return } @@ -101,9 +101,9 @@ func UnpinIssue(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -111,13 +111,13 @@ func UnpinIssue(ctx *context.APIContext) { // If we don't do this, it will crash when trying to add the unpin event to the comment history err = issue.LoadRepo(ctx) if err != nil { - ctx.Error(http.StatusInternalServerError, "LoadRepo", err) + ctx.APIErrorInternal(err) return } - err = issue.Unpin(ctx, ctx.Doer) + err = issues_model.UnpinIssue(ctx, issue, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "UnpinIssue", err) + ctx.APIErrorInternal(err) return } @@ -162,16 +162,16 @@ func MoveIssuePin(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } - err = issue.MovePin(ctx, int(ctx.PathParamInt64("position"))) + err = issues_model.MovePin(ctx, issue, int(ctx.PathParamInt64("position"))) if err != nil { - ctx.Error(http.StatusInternalServerError, "MovePin", err) + ctx.APIErrorInternal(err) return } @@ -203,7 +203,7 @@ func ListPinnedIssues(ctx *context.APIContext) { // "$ref": "#/responses/notFound" issues, err := issues_model.GetPinnedIssues(ctx, ctx.Repo.Repository.ID, false) if err != nil { - ctx.Error(http.StatusInternalServerError, "LoadPinnedIssues", err) + ctx.APIErrorInternal(err) return } @@ -235,29 +235,29 @@ func ListPinnedPullRequests(ctx *context.APIContext) { // "$ref": "#/responses/notFound" issues, err := issues_model.GetPinnedIssues(ctx, ctx.Repo.Repository.ID, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "LoadPinnedPullRequests", err) + ctx.APIErrorInternal(err) return } apiPrs := make([]*api.PullRequest, len(issues)) if err := issues.LoadPullRequests(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadPullRequests", err) + ctx.APIErrorInternal(err) return } for i, currentIssue := range issues { pr := currentIssue.PullRequest if err = pr.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } if err = pr.LoadBaseRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadBaseRepo", err) + ctx.APIErrorInternal(err) return } if err = pr.LoadHeadRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err) + ctx.APIErrorInternal(err) return } @@ -295,13 +295,13 @@ func AreNewIssuePinsAllowed(ctx *context.APIContext) { pinsAllowed.Issues, err = issues_model.IsNewPinAllowed(ctx, ctx.Repo.Repository.ID, false) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsNewIssuePinAllowed", err) + ctx.APIErrorInternal(err) return } pinsAllowed.PullRequests, err = issues_model.IsNewPinAllowed(ctx, ctx.Repo.Repository.ID, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsNewPullRequestPinAllowed", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go index ead86a717fae2..e535b5e0091dd 100644 --- a/routers/api/v1/repo/issue_reaction.go +++ b/routers/api/v1/repo/issue_reaction.go @@ -54,36 +54,36 @@ func GetIssueCommentReactions(ctx *context.APIContext) { comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrCommentNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) + ctx.APIErrorInternal(err) } return } if err := comment.LoadIssue(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "comment.LoadIssue", err) + ctx.APIErrorInternal(err) return } if comment.Issue.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) { - ctx.Error(http.StatusForbidden, "GetIssueCommentReactions", errors.New("no permission to get reactions")) + ctx.APIError(http.StatusForbidden, errors.New("no permission to get reactions")) return } reactions, _, err := issues_model.FindCommentReactions(ctx, comment.IssueID, comment.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindCommentReactions", err) + ctx.APIErrorInternal(err) return } _, err = reactions.LoadUsers(ctx, ctx.Repo.Repository) if err != nil { - ctx.Error(http.StatusInternalServerError, "ReactionList.LoadUsers()", err) + ctx.APIErrorInternal(err) return } @@ -191,30 +191,30 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp comment, err := issues_model.GetCommentByID(ctx, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrCommentNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) + ctx.APIErrorInternal(err) } return } if err = comment.LoadIssue(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "comment.LoadIssue() failed", err) + ctx.APIErrorInternal(err) return } if comment.Issue.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) { - ctx.NotFound() + ctx.APIErrorNotFound() return } if comment.Issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull) { - ctx.Error(http.StatusForbidden, "ChangeIssueCommentReaction", errors.New("no permission to change reaction")) + ctx.APIError(http.StatusForbidden, errors.New("no permission to change reaction")) return } @@ -223,7 +223,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp reaction, err := issue_service.CreateCommentReaction(ctx, ctx.Doer, comment, form.Reaction) if err != nil { if issues_model.IsErrForbiddenIssueReaction(err) || errors.Is(err, user_model.ErrBlockedUser) { - ctx.Error(http.StatusForbidden, err.Error(), err) + ctx.APIError(http.StatusForbidden, err) } else if issues_model.IsErrReactionAlreadyExist(err) { ctx.JSON(http.StatusOK, api.Reaction{ User: convert.ToUser(ctx, ctx.Doer, ctx.Doer), @@ -231,7 +231,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp Created: reaction.CreatedUnix.AsTime(), }) } else { - ctx.Error(http.StatusInternalServerError, "CreateCommentReaction", err) + ctx.APIErrorInternal(err) } return } @@ -245,7 +245,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp // DeleteIssueCommentReaction part err = issues_model.DeleteCommentReaction(ctx, ctx.Doer.ID, comment.Issue.ID, comment.ID, form.Reaction) if err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteCommentReaction", err) + ctx.APIErrorInternal(err) return } // ToDo respond 204 @@ -298,26 +298,26 @@ func GetIssueReactions(ctx *context.APIContext) { issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) { - ctx.Error(http.StatusForbidden, "GetIssueReactions", errors.New("no permission to get reactions")) + ctx.APIError(http.StatusForbidden, errors.New("no permission to get reactions")) return } reactions, count, err := issues_model.FindIssueReactions(ctx, issue.ID, utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindIssueReactions", err) + ctx.APIErrorInternal(err) return } _, err = reactions.LoadUsers(ctx, ctx.Repo.Repository) if err != nil { - ctx.Error(http.StatusInternalServerError, "ReactionList.LoadUsers()", err) + ctx.APIErrorInternal(err) return } @@ -422,15 +422,15 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.Error(http.StatusForbidden, "ChangeIssueCommentReaction", errors.New("no permission to change reaction")) + ctx.APIError(http.StatusForbidden, errors.New("no permission to change reaction")) return } @@ -439,7 +439,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.Error(http.StatusForbidden, err.Error(), err) + ctx.APIError(http.StatusForbidden, err) } else if issues_model.IsErrReactionAlreadyExist(err) { ctx.JSON(http.StatusOK, api.Reaction{ User: convert.ToUser(ctx, ctx.Doer, ctx.Doer), @@ -447,7 +447,7 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i Created: reaction.CreatedUnix.AsTime(), }) } else { - ctx.Error(http.StatusInternalServerError, "CreateIssueReaction", err) + ctx.APIErrorInternal(err) } return } @@ -461,7 +461,7 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i // DeleteIssueReaction part err = issues_model.DeleteIssueReaction(ctx, ctx.Doer.ID, issue.ID, form.Reaction) if err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteIssueReaction", err) + ctx.APIErrorInternal(err) return } // ToDo respond 204 diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go index e7fba6d0ed183..b18e172b37010 100644 --- a/routers/api/v1/repo/issue_stopwatch.go +++ b/routers/api/v1/repo/issue_stopwatch.go @@ -55,7 +55,7 @@ func StartIssueStopwatch(ctx *context.APIContext) { } if err := issues_model.CreateIssueStopwatch(ctx, ctx.Doer, issue); err != nil { - ctx.Error(http.StatusInternalServerError, "CreateOrStopIssueStopwatch", err) + ctx.APIErrorInternal(err) return } @@ -104,7 +104,7 @@ func StopIssueStopwatch(ctx *context.APIContext) { } if err := issues_model.FinishIssueStopwatch(ctx, ctx.Doer, issue); err != nil { - ctx.Error(http.StatusInternalServerError, "CreateOrStopIssueStopwatch", err) + ctx.APIErrorInternal(err) return } @@ -153,7 +153,7 @@ func DeleteIssueStopwatch(ctx *context.APIContext) { } if err := issues_model.CancelStopwatch(ctx, ctx.Doer, issue); err != nil { - ctx.Error(http.StatusInternalServerError, "CancelStopwatch", err) + ctx.APIErrorInternal(err) return } @@ -164,9 +164,9 @@ func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*issues_m issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return nil, err @@ -184,10 +184,10 @@ func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*issues_m if issues_model.StopwatchExists(ctx, ctx.Doer.ID, issue.ID) != shouldExist { if shouldExist { - ctx.Error(http.StatusConflict, "StopwatchExists", "cannot stop/cancel a non existent stopwatch") + ctx.APIError(http.StatusConflict, "cannot stop/cancel a non existent stopwatch") err = errors.New("cannot stop/cancel a non existent stopwatch") } else { - ctx.Error(http.StatusConflict, "StopwatchExists", "cannot start a stopwatch again if it already exists") + ctx.APIError(http.StatusConflict, "cannot start a stopwatch again if it already exists") err = errors.New("cannot start a stopwatch again if it already exists") } return nil, err @@ -220,19 +220,19 @@ func GetStopwatches(ctx *context.APIContext) { sws, err := issues_model.GetUserStopwatches(ctx, ctx.Doer.ID, utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserStopwatches", err) + ctx.APIErrorInternal(err) return } count, err := issues_model.CountUserStopwatches(ctx, ctx.Doer.ID) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } apiSWs, err := convert.ToStopWatches(ctx, sws) if err != nil { - ctx.Error(http.StatusInternalServerError, "APIFormat", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index 4fb80b1ec4f35..21e549496dfac 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -107,9 +107,9 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return @@ -118,9 +118,9 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { user, err := user_model.GetUserByName(ctx, ctx.PathParam("user")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return @@ -128,13 +128,13 @@ 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.Error(http.StatusForbidden, "User", fmt.Errorf("%s is not permitted to change subscriptions for %s", ctx.Doer.Name, user.Name)) + ctx.APIError(http.StatusForbidden, fmt.Errorf("%s is not permitted to change subscriptions for %s", ctx.Doer.Name, user.Name)) return } current, err := issues_model.CheckIssueWatch(ctx, user, issue) if err != nil { - ctx.Error(http.StatusInternalServerError, "CheckIssueWatch", err) + ctx.APIErrorInternal(err) return } @@ -146,7 +146,7 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { // Update watch state if err := issues_model.CreateOrUpdateIssueWatch(ctx, user.ID, issue.ID, watch); err != nil { - ctx.Error(http.StatusInternalServerError, "CreateOrUpdateIssueWatch", err) + ctx.APIErrorInternal(err) return } @@ -188,9 +188,9 @@ func CheckIssueSubscription(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return @@ -198,7 +198,7 @@ func CheckIssueSubscription(ctx *context.APIContext) { watching, err := issues_model.CheckIssueWatch(ctx, ctx.Doer, issue) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, api.WatchInfo{ @@ -254,9 +254,9 @@ func GetIssueSubscribers(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return @@ -264,7 +264,7 @@ func GetIssueSubscribers(ctx *context.APIContext) { iwl, err := issues_model.GetIssueWatchers(ctx, issue.ID, utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetIssueWatchers", err) + ctx.APIErrorInternal(err) return } @@ -275,7 +275,7 @@ func GetIssueSubscribers(ctx *context.APIContext) { users, err := user_model.GetUsersByIDs(ctx, userIDs) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUsersByIDs", err) + ctx.APIErrorInternal(err) return } apiUsers := make([]*api.User, 0, len(users)) @@ -285,7 +285,7 @@ func GetIssueSubscribers(ctx *context.APIContext) { count, err := issues_model.CountIssueWatchers(ctx, issue.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "CountIssueWatchers", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go index 57961b0660548..dbb2afa920eeb 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -72,15 +72,15 @@ func ListTrackedTimes(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !ctx.Repo.Repository.IsTimetrackerEnabled(ctx) { - ctx.NotFound("Timetracker is disabled") + ctx.APIErrorNotFound("Timetracker is disabled") return } issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -95,16 +95,16 @@ func ListTrackedTimes(ctx *context.APIContext) { if qUser != "" { user, err := user_model.GetUserByName(ctx, qUser) if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusNotFound, "User does not exist", err) + ctx.APIError(http.StatusNotFound, err) } else if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) return } opts.UserID = user.ID } if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = context.GetQueryBeforeSince(ctx.Base); err != nil { - ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } @@ -116,24 +116,24 @@ func ListTrackedTimes(ctx *context.APIContext) { if opts.UserID == 0 { opts.UserID = ctx.Doer.ID } else { - ctx.Error(http.StatusForbidden, "", fmt.Errorf("query by user not allowed; not enough rights")) + ctx.APIError(http.StatusForbidden, fmt.Errorf("query by user not allowed; not enough rights")) return } } count, err := issues_model.CountTrackedTimes(ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) + ctx.APIErrorInternal(err) return } if err = trackedTimes.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } @@ -184,16 +184,16 @@ func AddTime(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } if !ctx.Repo.CanUseTimetracker(ctx, issue, ctx.Doer) { if !ctx.Repo.Repository.IsTimetrackerEnabled(ctx) { - ctx.Error(http.StatusBadRequest, "", "time tracking disabled") + ctx.APIError(http.StatusBadRequest, "time tracking disabled") return } ctx.Status(http.StatusForbidden) @@ -206,7 +206,7 @@ func AddTime(ctx *context.APIContext) { // allow only RepoAdmin, Admin and User to add time user, err = user_model.GetUserByName(ctx, form.User) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } } } @@ -218,11 +218,11 @@ func AddTime(ctx *context.APIContext) { trackedTime, err := issues_model.AddTime(ctx, user, issue, form.Time, created) if err != nil { - ctx.Error(http.StatusInternalServerError, "AddTime", err) + ctx.APIErrorInternal(err) return } if err = trackedTime.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToTrackedTime(ctx, user, trackedTime)) @@ -267,9 +267,9 @@ func ResetIssueTime(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -286,9 +286,9 @@ func ResetIssueTime(ctx *context.APIContext) { err = issues_model.DeleteIssueUserTimes(ctx, issue, ctx.Doer) if err != nil { if db.IsErrNotExist(err) { - ctx.Error(http.StatusNotFound, "DeleteIssueUserTimes", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "DeleteIssueUserTimes", err) + ctx.APIErrorInternal(err) } return } @@ -340,9 +340,9 @@ func DeleteTime(ctx *context.APIContext) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -359,14 +359,14 @@ func DeleteTime(ctx *context.APIContext) { time, err := issues_model.GetTrackedTimeByID(ctx, ctx.PathParamInt64("id")) if err != nil { if db.IsErrNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) return } - ctx.Error(http.StatusInternalServerError, "GetTrackedTimeByID", err) + ctx.APIErrorInternal(err) return } if time.Deleted { - ctx.NotFound(fmt.Errorf("tracked time [%d] already deleted", time.ID)) + ctx.APIErrorNotFound(fmt.Errorf("tracked time [%d] already deleted", time.ID)) return } @@ -378,7 +378,7 @@ func DeleteTime(ctx *context.APIContext) { err = issues_model.DeleteTime(ctx, time) if err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteTime", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -419,25 +419,25 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !ctx.Repo.Repository.IsTimetrackerEnabled(ctx) { - ctx.Error(http.StatusBadRequest, "", "time tracking disabled") + ctx.APIError(http.StatusBadRequest, "time tracking disabled") return } user, err := user_model.GetUserByName(ctx, ctx.PathParam("timetrackingusername")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return } if user == nil { - ctx.NotFound() + ctx.APIErrorNotFound() return } if !ctx.IsUserRepoAdmin() && !ctx.Doer.IsAdmin && ctx.Doer.ID != user.ID { - ctx.Error(http.StatusForbidden, "", fmt.Errorf("query by user not allowed; not enough rights")) + ctx.APIError(http.StatusForbidden, fmt.Errorf("query by user not allowed; not enough rights")) return } @@ -448,11 +448,11 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) + ctx.APIErrorInternal(err) return } if err = trackedTimes.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToTrackedTimeList(ctx, ctx.Doer, trackedTimes)) @@ -509,7 +509,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !ctx.Repo.Repository.IsTimetrackerEnabled(ctx) { - ctx.Error(http.StatusBadRequest, "", "time tracking disabled") + ctx.APIError(http.StatusBadRequest, "time tracking disabled") return } @@ -523,9 +523,9 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { if qUser != "" { user, err := user_model.GetUserByName(ctx, qUser) if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusNotFound, "User does not exist", err) + ctx.APIError(http.StatusNotFound, err) } else if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) return } opts.UserID = user.ID @@ -533,7 +533,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { var err error if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = context.GetQueryBeforeSince(ctx.Base); err != nil { - ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } @@ -545,24 +545,24 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { if opts.UserID == 0 { opts.UserID = ctx.Doer.ID } else { - ctx.Error(http.StatusForbidden, "", fmt.Errorf("query by user not allowed; not enough rights")) + ctx.APIError(http.StatusForbidden, fmt.Errorf("query by user not allowed; not enough rights")) return } } count, err := issues_model.CountTrackedTimes(ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) + ctx.APIErrorInternal(err) return } if err = trackedTimes.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } @@ -607,24 +607,24 @@ func ListMyTrackedTimes(ctx *context.APIContext) { var err error if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = context.GetQueryBeforeSince(ctx.Base); err != nil { - ctx.Error(http.StatusUnprocessableEntity, "GetQueryBeforeSince", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } count, err := issues_model.CountTrackedTimes(ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } trackedTimes, err := issues_model.GetTrackedTimes(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByUser", err) + ctx.APIErrorInternal(err) return } if err = trackedTimes.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go index 23cc9226287d2..8cb61e9e0c1c0 100644 --- a/routers/api/v1/repo/key.go +++ b/routers/api/v1/repo/key.go @@ -92,7 +92,7 @@ func ListDeployKeys(ctx *context.APIContext) { keys, count, err := db.FindAndCount[asymkey_model.DeployKey](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -100,7 +100,7 @@ func ListDeployKeys(ctx *context.APIContext) { apiKeys := make([]*api.DeployKey, len(keys)) for i := range keys { if err := keys[i].GetContent(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "GetContent", err) + ctx.APIErrorInternal(err) return } apiKeys[i] = convert.ToDeployKey(apiLink, keys[i]) @@ -146,21 +146,21 @@ func GetDeployKey(ctx *context.APIContext) { key, err := asymkey_model.GetDeployKeyByID(ctx, ctx.PathParamInt64("id")) if err != nil { if asymkey_model.IsErrDeployKeyNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetDeployKeyByID", err) + ctx.APIErrorInternal(err) } return } // this check make it more consistent if key.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } if err = key.GetContent(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "GetContent", err) + ctx.APIErrorInternal(err) return } @@ -175,11 +175,11 @@ func GetDeployKey(ctx *context.APIContext) { // HandleCheckKeyStringError handle check key error func HandleCheckKeyStringError(ctx *context.APIContext, err error) { if db.IsErrSSHDisabled(err) { - ctx.Error(http.StatusUnprocessableEntity, "", "SSH is disabled") + ctx.APIError(http.StatusUnprocessableEntity, "SSH is disabled") } else if asymkey_model.IsErrKeyUnableVerify(err) { - ctx.Error(http.StatusUnprocessableEntity, "", "Unable to verify key content") + ctx.APIError(http.StatusUnprocessableEntity, "Unable to verify key content") } else { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid key content: %w", err)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid key content: %w", err)) } } @@ -187,15 +187,15 @@ func HandleCheckKeyStringError(ctx *context.APIContext, err error) { func HandleAddKeyError(ctx *context.APIContext, err error) { switch { case asymkey_model.IsErrDeployKeyAlreadyExist(err): - ctx.Error(http.StatusUnprocessableEntity, "", "This key has already been added to this repository") + ctx.APIError(http.StatusUnprocessableEntity, "This key has already been added to this repository") case asymkey_model.IsErrKeyAlreadyExist(err): - ctx.Error(http.StatusUnprocessableEntity, "", "Key content has been used as non-deploy key") + ctx.APIError(http.StatusUnprocessableEntity, "Key content has been used as non-deploy key") case asymkey_model.IsErrKeyNameAlreadyUsed(err): - ctx.Error(http.StatusUnprocessableEntity, "", "Key title has been used") + ctx.APIError(http.StatusUnprocessableEntity, "Key title has been used") case asymkey_model.IsErrDeployKeyNameAlreadyUsed(err): - ctx.Error(http.StatusUnprocessableEntity, "", "A key with the same name already exists") + ctx.APIError(http.StatusUnprocessableEntity, "A key with the same name already exists") default: - ctx.Error(http.StatusInternalServerError, "AddKey", err) + ctx.APIErrorInternal(err) } } @@ -281,9 +281,9 @@ func DeleteDeploykey(ctx *context.APIContext) { if err := asymkey_service.DeleteDeployKey(ctx, ctx.Repo.Repository, ctx.PathParamInt64("id")); err != nil { if asymkey_model.IsErrKeyAccessDenied(err) { - ctx.Error(http.StatusForbidden, "", "You do not have access to this key") + ctx.APIError(http.StatusForbidden, "You do not have access to this key") } else { - ctx.Error(http.StatusInternalServerError, "DeleteDeployKey", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go index 1ece2521e0f1f..4f79d4259538d 100644 --- a/routers/api/v1/repo/label.go +++ b/routers/api/v1/repo/label.go @@ -51,13 +51,13 @@ func ListLabels(ctx *context.APIContext) { labels, err := issues_model.GetLabelsByRepoID(ctx, ctx.Repo.Repository.ID, ctx.FormString("sort"), utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelsByRepoID", err) + ctx.APIErrorInternal(err) return } count, err := issues_model.CountLabelsByRepoID(ctx, ctx.Repo.Repository.ID) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -107,9 +107,9 @@ func GetLabel(ctx *context.APIContext) { } if err != nil { if issues_model.IsErrRepoLabelNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) + ctx.APIErrorInternal(err) } return } @@ -153,7 +153,7 @@ func CreateLabel(ctx *context.APIContext) { color, err := label.NormalizeColor(form.Color) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "StringToColor", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } form.Color = color @@ -166,7 +166,7 @@ func CreateLabel(ctx *context.APIContext) { } l.SetArchived(form.IsArchived) if err := issues_model.NewLabel(ctx, l); err != nil { - ctx.Error(http.StatusInternalServerError, "NewLabel", err) + ctx.APIErrorInternal(err) return } @@ -215,9 +215,9 @@ func EditLabel(ctx *context.APIContext) { l, err := issues_model.GetLabelInRepoByID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrRepoLabelNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) + ctx.APIErrorInternal(err) } return } @@ -231,7 +231,7 @@ func EditLabel(ctx *context.APIContext) { if form.Color != nil { color, err := label.NormalizeColor(*form.Color) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "StringToColor", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } l.Color = color @@ -241,7 +241,7 @@ func EditLabel(ctx *context.APIContext) { } l.SetArchived(form.IsArchived != nil && *form.IsArchived) if err := issues_model.UpdateLabel(ctx, l); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateLabel", err) + ctx.APIErrorInternal(err) return } @@ -277,7 +277,7 @@ func DeleteLabel(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if err := issues_model.DeleteLabel(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("id")); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteLabel", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/language.go b/routers/api/v1/repo/language.go index f1d5bbe45fe72..00789983ce711 100644 --- a/routers/api/v1/repo/language.go +++ b/routers/api/v1/repo/language.go @@ -70,7 +70,7 @@ func GetLanguages(ctx *context.APIContext) { langs, err := repo_model.GetLanguageStats(ctx, ctx.Repo.Repository) if err != nil { log.Error("GetLanguageStats failed: %v", err) - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/license.go b/routers/api/v1/repo/license.go index 8a6bdfd42fa69..3040815e8ae34 100644 --- a/routers/api/v1/repo/license.go +++ b/routers/api/v1/repo/license.go @@ -38,7 +38,7 @@ func GetLicenses(ctx *context.APIContext) { licenses, err := repo_model.GetRepoLicenses(ctx, ctx.Repo.Repository) if err != nil { log.Error("GetRepoLicenses failed: %v", err) - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go index 452825c0a3ef1..d7508684a1237 100644 --- a/routers/api/v1/repo/migrate.go +++ b/routers/api/v1/repo/migrate.go @@ -72,21 +72,21 @@ func Migrate(ctx *context.APIContext) { } if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "GetUser", err) + ctx.APIErrorInternal(err) } return } if ctx.HasAPIError() { - ctx.Error(http.StatusUnprocessableEntity, "", ctx.GetErrMsg()) + ctx.APIError(http.StatusUnprocessableEntity, ctx.GetErrMsg()) return } if !ctx.Doer.IsAdmin { if !repoOwner.IsOrganization() && ctx.Doer.ID != repoOwner.ID { - ctx.Error(http.StatusForbidden, "", "Given user is not an organization.") + ctx.APIError(http.StatusForbidden, "Given user is not an organization.") return } @@ -94,10 +94,10 @@ func Migrate(ctx *context.APIContext) { // Check ownership of organization. isOwner, err := organization.OrgFromUser(repoOwner).IsOwnedBy(ctx, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOwnedBy", err) + ctx.APIErrorInternal(err) return } else if !isOwner { - ctx.Error(http.StatusForbidden, "", "Given user is not owner of organization.") + ctx.APIError(http.StatusForbidden, "Given user is not owner of organization.") return } } @@ -115,12 +115,12 @@ func Migrate(ctx *context.APIContext) { gitServiceType := convert.ToGitServiceType(form.Service) if form.Mirror && setting.Mirror.DisableNewPull { - ctx.Error(http.StatusForbidden, "MirrorsGlobalDisabled", fmt.Errorf("the site administrator has disabled the creation of new pull mirrors")) + ctx.APIError(http.StatusForbidden, fmt.Errorf("the site administrator has disabled the creation of new pull mirrors")) return } if setting.Repository.DisableMigrations { - ctx.Error(http.StatusForbidden, "MigrationsGlobalDisabled", fmt.Errorf("the site administrator has disabled migrations")) + ctx.APIError(http.StatusForbidden, fmt.Errorf("the site administrator has disabled migrations")) return } @@ -129,7 +129,7 @@ func Migrate(ctx *context.APIContext) { if form.LFS && len(form.LFSEndpoint) > 0 { ep := lfs.DetermineEndpoint("", form.LFSEndpoint) if ep == nil { - ctx.Error(http.StatusInternalServerError, "", ctx.Tr("repo.migrate.invalid_lfs_endpoint")) + ctx.APIErrorInternal(errors.New("the LFS endpoint is not valid")) return } err = migrations.IsMigrateURLAllowed(ep.String(), ctx.Doer) @@ -221,35 +221,35 @@ func Migrate(ctx *context.APIContext) { func handleMigrateError(ctx *context.APIContext, repoOwner *user_model.User, err error) { switch { case repo_model.IsErrRepoAlreadyExist(err): - ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.") + ctx.APIError(http.StatusConflict, "The repository with the same name already exists.") case repo_model.IsErrRepoFilesAlreadyExist(err): - ctx.Error(http.StatusConflict, "", "Files already exist for this repository. Adopt them or delete them.") + ctx.APIError(http.StatusConflict, "Files already exist for this repository. Adopt them or delete them.") case migrations.IsRateLimitError(err): - ctx.Error(http.StatusUnprocessableEntity, "", "Remote visit addressed rate limitation.") + ctx.APIError(http.StatusUnprocessableEntity, "Remote visit addressed rate limitation.") case migrations.IsTwoFactorAuthError(err): - ctx.Error(http.StatusUnprocessableEntity, "", "Remote visit required two factors authentication.") + ctx.APIError(http.StatusUnprocessableEntity, "Remote visit required two factors authentication.") case repo_model.IsErrReachLimitOfRepo(err): - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("You have already reached your limit of %d repositories.", repoOwner.MaxCreationLimit())) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("You have already reached your limit of %d repositories.", repoOwner.MaxCreationLimit())) case db.IsErrNameReserved(err): - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("The username '%s' is reserved.", err.(db.ErrNameReserved).Name)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("The username '%s' is reserved.", err.(db.ErrNameReserved).Name)) case db.IsErrNameCharsNotAllowed(err): - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("The username '%s' contains invalid characters.", err.(db.ErrNameCharsNotAllowed).Name)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("The username '%s' contains invalid characters.", err.(db.ErrNameCharsNotAllowed).Name)) case db.IsErrNamePatternNotAllowed(err): - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("The pattern '%s' is not allowed in a username.", err.(db.ErrNamePatternNotAllowed).Pattern)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("The pattern '%s' is not allowed in a username.", err.(db.ErrNamePatternNotAllowed).Pattern)) case git.IsErrInvalidCloneAddr(err): - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) case base.IsErrNotSupported(err): - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) default: err = util.SanitizeErrorCredentialURLs(err) if strings.Contains(err.Error(), "Authentication failed") || strings.Contains(err.Error(), "Bad credentials") || strings.Contains(err.Error(), "could not read Username") { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Authentication failed: %v.", err)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Authentication failed: %v.", err)) } else if strings.Contains(err.Error(), "fatal:") { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Migration failed: %v.", err)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Migration failed: %v.", err)) } else { - ctx.Error(http.StatusInternalServerError, "MigrateRepository", err) + ctx.APIErrorInternal(err) } } } @@ -259,19 +259,19 @@ func handleRemoteAddrError(ctx *context.APIContext, err error) { addrErr := err.(*git.ErrInvalidCloneAddr) switch { case addrErr.IsURLError: - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) case addrErr.IsPermissionDenied: if addrErr.LocalPath { - ctx.Error(http.StatusUnprocessableEntity, "", "You are not allowed to import local repositories.") + ctx.APIError(http.StatusUnprocessableEntity, "You are not allowed to import local repositories.") } else { - ctx.Error(http.StatusUnprocessableEntity, "", "You can not import from disallowed hosts.") + ctx.APIError(http.StatusUnprocessableEntity, "You can not import from disallowed hosts.") } case addrErr.IsInvalidPath: - ctx.Error(http.StatusUnprocessableEntity, "", "Invalid local path, it does not exist or not a directory.") + ctx.APIError(http.StatusUnprocessableEntity, "Invalid local path, it does not exist or not a directory.") default: - ctx.Error(http.StatusInternalServerError, "ParseRemoteAddr", "Unknown error type (ErrInvalidCloneAddr): "+err.Error()) + ctx.APIErrorInternal(fmt.Errorf("unknown error type (ErrInvalidCloneAddr): %w", err)) } } else { - ctx.Error(http.StatusInternalServerError, "ParseRemoteAddr", err) + ctx.APIErrorInternal(err) } } diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go index 8d7516491ed33..33fa7c4b1644c 100644 --- a/routers/api/v1/repo/milestone.go +++ b/routers/api/v1/repo/milestone.go @@ -74,7 +74,7 @@ func ListMilestones(ctx *context.APIContext) { Name: ctx.FormString("name"), }) if err != nil { - ctx.Error(http.StatusInternalServerError, "db.FindAndCount[issues_model.Milestone]", err) + ctx.APIErrorInternal(err) return } @@ -173,7 +173,7 @@ func CreateMilestone(ctx *context.APIContext) { } if err := issues_model.NewMilestone(ctx, milestone); err != nil { - ctx.Error(http.StatusInternalServerError, "NewMilestone", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusCreated, convert.ToAPIMilestone(milestone)) @@ -233,7 +233,7 @@ func EditMilestone(ctx *context.APIContext) { } if err := issues_model.UpdateMilestone(ctx, milestone, oldIsClosed); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateMilestone", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToAPIMilestone(milestone)) @@ -272,7 +272,7 @@ func DeleteMilestone(ctx *context.APIContext) { } if err := issues_model.DeleteMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, m.ID); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteMilestoneByRepoID", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) @@ -288,7 +288,7 @@ func getMilestoneByIDOrName(ctx *context.APIContext) *issues_model.Milestone { if err == nil { return milestone } else if !issues_model.IsErrMilestoneNotExist(err) { - ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err) + ctx.APIErrorInternal(err) return nil } } @@ -296,10 +296,10 @@ func getMilestoneByIDOrName(ctx *context.APIContext) *issues_model.Milestone { milestone, err := issues_model.GetMilestoneByRepoIDANDName(ctx, ctx.Repo.Repository.ID, mile) if err != nil { if issues_model.IsErrMilestoneNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return nil } - ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err) + ctx.APIErrorInternal(err) return nil } diff --git a/routers/api/v1/repo/mirror.go b/routers/api/v1/repo/mirror.go index c911f6830cb95..b5f4c12c5017d 100644 --- a/routers/api/v1/repo/mirror.go +++ b/routers/api/v1/repo/mirror.go @@ -53,20 +53,20 @@ func MirrorSync(ctx *context.APIContext) { repo := ctx.Repo.Repository if !ctx.Repo.CanWrite(unit.TypeCode) { - ctx.Error(http.StatusForbidden, "MirrorSync", "Must have write access") + ctx.APIError(http.StatusForbidden, "Must have write access") } if !setting.Mirror.Enabled { - ctx.Error(http.StatusBadRequest, "MirrorSync", "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") return } if _, err := repo_model.GetMirrorByRepoID(ctx, repo.ID); err != nil { if errors.Is(err, repo_model.ErrMirrorNotExist) { - ctx.Error(http.StatusBadRequest, "MirrorSync", "Repository is not a mirror") + ctx.APIError(http.StatusBadRequest, "Repository is not a mirror") return } - ctx.Error(http.StatusInternalServerError, "MirrorSync", err) + ctx.APIErrorInternal(err) return } @@ -104,19 +104,19 @@ func PushMirrorSync(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !setting.Mirror.Enabled { - ctx.Error(http.StatusBadRequest, "PushMirrorSync", "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") return } // Get All push mirrors of a specific repo pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, ctx.Repo.Repository.ID, db.ListOptions{}) if err != nil { - ctx.Error(http.StatusNotFound, "PushMirrorSync", err) + ctx.APIError(http.StatusNotFound, err) return } for _, mirror := range pushMirrors { ok := mirror_service.SyncPushMirror(ctx, mirror.ID) if !ok { - ctx.Error(http.StatusInternalServerError, "PushMirrorSync", "error occurred when syncing push mirror "+mirror.RemoteName) + ctx.APIErrorInternal(errors.New("error occurred when syncing push mirror " + mirror.RemoteName)) return } } @@ -161,7 +161,7 @@ func ListPushMirrors(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !setting.Mirror.Enabled { - ctx.Error(http.StatusBadRequest, "GetPushMirrorsByRepoID", "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") return } @@ -169,7 +169,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.Error(http.StatusNotFound, "GetPushMirrorsByRepoID", err) + ctx.APIError(http.StatusNotFound, err) return } @@ -219,7 +219,7 @@ func GetPushMirrorByName(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !setting.Mirror.Enabled { - ctx.Error(http.StatusBadRequest, "GetPushMirrorByRemoteName", "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") return } @@ -230,16 +230,16 @@ func GetPushMirrorByName(ctx *context.APIContext) { RemoteName: mirrorName, }.ToConds()) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetPushMirrors", err) + ctx.APIErrorInternal(err) return } else if !exist { - ctx.Error(http.StatusNotFound, "GetPushMirrors", nil) + ctx.APIError(http.StatusNotFound, nil) return } m, err := convert.ToPushMirror(ctx, pushMirror) if err != nil { - ctx.ServerError("GetPushMirrorByRemoteName", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, m) @@ -280,7 +280,7 @@ func AddPushMirror(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !setting.Mirror.Enabled { - ctx.Error(http.StatusBadRequest, "AddPushMirror", "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") return } @@ -320,7 +320,7 @@ func DeletePushMirrorByRemoteName(ctx *context.APIContext) { // "$ref": "#/responses/error" if !setting.Mirror.Enabled { - ctx.Error(http.StatusBadRequest, "DeletePushMirrorByName", "Mirror feature is disabled") + ctx.APIError(http.StatusBadRequest, "Mirror feature is disabled") return } @@ -328,7 +328,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.Error(http.StatusNotFound, "DeletePushMirrors", err) + ctx.APIError(http.StatusNotFound, err) return } ctx.Status(http.StatusNoContent) @@ -339,7 +339,7 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro interval, err := time.ParseDuration(mirrorOption.Interval) if err != nil || (interval != 0 && interval < setting.Mirror.MinInterval) { - ctx.Error(http.StatusBadRequest, "CreatePushMirror", err) + ctx.APIError(http.StatusBadRequest, err) return } @@ -354,13 +354,13 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro remoteSuffix, err := util.CryptoRandomString(10) if err != nil { - ctx.ServerError("CryptoRandomString", err) + ctx.APIErrorInternal(err) return } remoteAddress, err := util.SanitizeURL(mirrorOption.RemoteAddress) if err != nil { - ctx.ServerError("SanitizeURL", err) + ctx.APIErrorInternal(err) return } @@ -374,22 +374,22 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro } if err = db.Insert(ctx, pushMirror); err != nil { - ctx.ServerError("InsertPushMirror", err) + ctx.APIErrorInternal(err) return } // if the registration of the push mirrorOption fails remove it from the database if err = mirror_service.AddPushMirrorRemote(ctx, pushMirror, address); err != nil { if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: pushMirror.ID, RepoID: pushMirror.RepoID}); err != nil { - ctx.ServerError("DeletePushMirrors", err) + ctx.APIErrorInternal(err) return } - ctx.ServerError("AddPushMirrorRemote", err) + ctx.APIErrorInternal(err) return } m, err := convert.ToPushMirror(ctx, pushMirror) if err != nil { - ctx.ServerError("ToPushMirror", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, m) @@ -400,13 +400,13 @@ func HandleRemoteAddressError(ctx *context.APIContext, err error) { addrErr := err.(*git.ErrInvalidCloneAddr) switch { case addrErr.IsProtocolInvalid: - ctx.Error(http.StatusBadRequest, "CreatePushMirror", "Invalid mirror protocol") + ctx.APIError(http.StatusBadRequest, "Invalid mirror protocol") case addrErr.IsURLError: - ctx.Error(http.StatusBadRequest, "CreatePushMirror", "Invalid Url ") + ctx.APIError(http.StatusBadRequest, "Invalid Url ") case addrErr.IsPermissionDenied: - ctx.Error(http.StatusUnauthorized, "CreatePushMirror", "Permission denied") + ctx.APIError(http.StatusUnauthorized, "Permission denied") default: - ctx.Error(http.StatusBadRequest, "CreatePushMirror", "Unknown error") + ctx.APIError(http.StatusBadRequest, "Unknown error") } return } diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go index 8fec844cc44ec..dcb512256c42c 100644 --- a/routers/api/v1/repo/notes.go +++ b/routers/api/v1/repo/notes.go @@ -54,7 +54,7 @@ func GetNote(ctx *context.APIContext) { sha := ctx.PathParam("sha") if !git.IsValidRefPattern(sha) { - ctx.Error(http.StatusUnprocessableEntity, "no valid ref or sha", fmt.Sprintf("no valid ref or sha: %s", sha)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("no valid ref or sha: %s", sha)) return } getNote(ctx, sha) @@ -62,16 +62,16 @@ func GetNote(ctx *context.APIContext) { func getNote(ctx *context.APIContext, identifier string) { if ctx.Repo.GitRepo == nil { - ctx.InternalServerError(fmt.Errorf("no open git repo")) + ctx.APIErrorInternal(fmt.Errorf("no open git repo")) return } commitID, err := ctx.Repo.GitRepo.ConvertToGitID(identifier) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "ConvertToSHA1", err) + ctx.APIErrorInternal(err) } return } @@ -79,10 +79,10 @@ func getNote(ctx *context.APIContext, identifier string) { var note git.Note if err := git.GetNote(ctx, ctx.Repo.GitRepo, commitID.String(), ¬e); err != nil { if git.IsErrNotExist(err) { - ctx.NotFound(identifier) + ctx.APIErrorNotFound(identifier) return } - ctx.Error(http.StatusInternalServerError, "GetNote", err) + ctx.APIErrorInternal(err) return } @@ -96,7 +96,7 @@ func getNote(ctx *context.APIContext, identifier string) { Files: files, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "ToCommit", err) + ctx.APIErrorInternal(err) return } apiNote := api.Note{Message: string(note.Message), Commit: cmt} diff --git a/routers/api/v1/repo/patch.go b/routers/api/v1/repo/patch.go index 95d7631da7be8..bcf498bf7ecb7 100644 --- a/routers/api/v1/repo/patch.go +++ b/routers/api/v1/repo/patch.go @@ -83,7 +83,7 @@ func ApplyDiffPatch(ctx *context.APIContext) { } if !canWriteFiles(ctx, apiOpts.BranchName) { - ctx.Error(http.StatusInternalServerError, "ApplyPatch", repo_model.ErrUserDoesNotHaveAccessToRepo{ + ctx.APIErrorInternal(repo_model.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.Doer.ID, RepoName: ctx.Repo.Repository.LowerName, }) @@ -93,19 +93,19 @@ func ApplyDiffPatch(ctx *context.APIContext) { fileResponse, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, opts) if err != nil { if files.IsErrUserCannotCommit(err) || pull_service.IsErrFilePathProtected(err) { - ctx.Error(http.StatusForbidden, "Access", err) + ctx.APIError(http.StatusForbidden, err) return } if git_model.IsErrBranchAlreadyExists(err) || files.IsErrFilenameInvalid(err) || pull_service.IsErrSHADoesNotMatch(err) || files.IsErrFilePathInvalid(err) || files.IsErrRepoFileAlreadyExists(err) { - ctx.Error(http.StatusUnprocessableEntity, "Invalid", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } if git_model.IsErrBranchNotExist(err) || git.IsErrBranchNotExist(err) { - ctx.Error(http.StatusNotFound, "BranchDoesNotExist", err) + ctx.APIError(http.StatusNotFound, err) return } - ctx.Error(http.StatusInternalServerError, "ApplyPatch", err) + ctx.APIErrorInternal(err) } else { ctx.JSON(http.StatusCreated, fileResponse) } diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index f7fdc93f81db6..1f61ac031abab 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -108,7 +108,7 @@ func ListPullRequests(ctx *context.APIContext) { labelIDs, err := base.StringsToInt64s(ctx.FormStrings("labels")) if err != nil { - ctx.Error(http.StatusInternalServerError, "PullRequests", err) + ctx.APIErrorInternal(err) return } var posterID int64 @@ -116,9 +116,9 @@ func ListPullRequests(ctx *context.APIContext) { poster, err := user_model.GetUserByName(ctx, posterStr) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusBadRequest, "Poster not found", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return } @@ -134,13 +134,13 @@ func ListPullRequests(ctx *context.APIContext) { PosterID: posterID, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "PullRequests", err) + ctx.APIErrorInternal(err) return } apiPrs, err := convert.ToAPIPullRequests(ctx, ctx.Repo.Repository, prs, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "ToAPIPullRequests", err) + ctx.APIErrorInternal(err) return } @@ -182,19 +182,19 @@ func GetPullRequest(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } if err = pr.LoadBaseRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadBaseRepo", err) + ctx.APIErrorInternal(err) return } if err = pr.LoadHeadRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToAPIPullRequest(ctx, pr, ctx.Doer)) @@ -252,9 +252,9 @@ func GetPullRequestByBaseHead(ctx *context.APIContext) { repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, owner, name) if err != nil { if repo_model.IsErrRepoNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetRepositoryByOwnerName", err) + ctx.APIErrorInternal(err) } return } @@ -267,19 +267,19 @@ func GetPullRequestByBaseHead(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByBaseHeadInfo(ctx, ctx.Repo.Repository.ID, headRepoID, ctx.PathParam("base"), headBranch) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByBaseHeadInfo", err) + ctx.APIErrorInternal(err) } return } if err = pr.LoadBaseRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadBaseRepo", err) + ctx.APIErrorInternal(err) return } if err = pr.LoadHeadRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToAPIPullRequest(ctx, pr, ctx.Doer)) @@ -327,9 +327,9 @@ func DownloadPullDiffOrPatch(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) } return } @@ -343,7 +343,7 @@ func DownloadPullDiffOrPatch(ctx *context.APIContext) { binary := ctx.FormBool("binary") if err := pull_service.DownloadDiffOrPatch(ctx, pr, ctx, patch, binary); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } } @@ -388,7 +388,7 @@ func CreatePullRequest(ctx *context.APIContext) { form := *web.GetForm(ctx).(*api.CreatePullRequestOption) if form.Head == form.Base { - ctx.Error(http.StatusUnprocessableEntity, "BaseHeadSame", "Invalid PullRequest: There are no changes between the head and the base") + ctx.APIError(http.StatusUnprocessableEntity, "Invalid PullRequest: There are no changes between the head and the base") return } @@ -406,7 +406,7 @@ func CreatePullRequest(ctx *context.APIContext) { defer closer() if !compareResult.baseRef.IsBranch() || !compareResult.headRef.IsBranch() { - ctx.Error(http.StatusUnprocessableEntity, "BaseHeadInvalidRefType", "Invalid PullRequest: base and head must be branches") + ctx.APIError(http.StatusUnprocessableEntity, "Invalid PullRequest: base and head must be branches") return } @@ -417,7 +417,7 @@ func CreatePullRequest(ctx *context.APIContext) { ) if err != nil { if !issues_model.IsErrPullRequestNotExist(err) { - ctx.Error(http.StatusInternalServerError, "GetUnmergedPullRequest", err) + ctx.APIErrorInternal(err) return } } else { @@ -429,14 +429,14 @@ func CreatePullRequest(ctx *context.APIContext) { HeadBranch: existingPr.HeadBranch, BaseBranch: existingPr.BaseBranch, } - ctx.Error(http.StatusConflict, "GetUnmergedPullRequest", err) + ctx.APIError(http.StatusConflict, err) return } if len(form.Labels) > 0 { labels, err := issues_model.GetLabelsInRepoByIDs(ctx, ctx.Repo.Repository.ID, form.Labels) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDs", err) + ctx.APIErrorInternal(err) return } @@ -448,7 +448,7 @@ func CreatePullRequest(ctx *context.APIContext) { if ctx.Repo.Owner.IsOrganization() { orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx, ctx.Repo.Owner.ID, form.Labels) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelsInOrgByIDs", err) + ctx.APIErrorInternal(err) return } @@ -464,9 +464,9 @@ func CreatePullRequest(ctx *context.APIContext) { milestone, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, form.Milestone) if err != nil { if issues_model.IsErrMilestoneNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err) + ctx.APIErrorInternal(fmt.Errorf("GetMilestoneByRepoID: %w", err)) } return } @@ -504,9 +504,9 @@ func CreatePullRequest(ctx *context.APIContext) { assigneeIDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(ctx, form.Assignee, form.Assignees) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Assignee does not exist: [name: %s]", err)) } else { - ctx.Error(http.StatusInternalServerError, "AddAssigneeByName", err) + ctx.APIErrorInternal(err) } return } @@ -514,17 +514,17 @@ func CreatePullRequest(ctx *context.APIContext) { for _, aID := range assigneeIDs { assignee, err := user_model.GetUserByID(ctx, aID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserByID", err) + ctx.APIErrorInternal(err) return } valid, err := access_model.CanBeAssigned(ctx, assignee, repo, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "canBeAssigned", err) + ctx.APIErrorInternal(err) return } if !valid { - ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) + ctx.APIError(http.StatusUnprocessableEntity, repo_model.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) return } } @@ -543,13 +543,13 @@ func CreatePullRequest(ctx *context.APIContext) { if err := pull_service.NewPullRequest(ctx, prOpts); err != nil { if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { - ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, user_model.ErrBlockedUser) { - ctx.Error(http.StatusForbidden, "BlockedUser", err) + ctx.APIError(http.StatusForbidden, err) } else if errors.Is(err, issues_model.ErrMustCollaborator) { - ctx.Error(http.StatusForbidden, "MustCollaborator", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "NewPullRequest", err) + ctx.APIErrorInternal(err) } return } @@ -606,23 +606,23 @@ func EditPullRequest(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } err = pr.LoadIssue(ctx) if err != nil { - ctx.Error(http.StatusInternalServerError, "LoadIssue", err) + ctx.APIErrorInternal(err) return } issue := pr.Issue issue.Repo = ctx.Repo.Repository if err := issue.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } @@ -634,7 +634,7 @@ func EditPullRequest(ctx *context.APIContext) { if len(form.Title) > 0 { err = issue_service.ChangeTitle(ctx, issue, ctx.Doer, form.Title) if err != nil { - ctx.Error(http.StatusInternalServerError, "ChangeTitle", err) + ctx.APIErrorInternal(err) return } } @@ -642,11 +642,11 @@ func EditPullRequest(ctx *context.APIContext) { err = issue_service.ChangeContent(ctx, issue, ctx.Doer, *form.Body, issue.ContentVersion) if err != nil { if errors.Is(err, issues_model.ErrIssueAlreadyChanged) { - ctx.Error(http.StatusBadRequest, "ChangeContent", err) + ctx.APIError(http.StatusBadRequest, err) return } - ctx.Error(http.StatusInternalServerError, "ChangeContent", err) + ctx.APIErrorInternal(err) return } } @@ -661,7 +661,7 @@ func EditPullRequest(ctx *context.APIContext) { } if err := issues_model.UpdateIssueDeadline(ctx, issue, deadlineUnix, ctx.Doer); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) + ctx.APIErrorInternal(err) return } issue.DeadlineUnix = deadlineUnix @@ -679,11 +679,11 @@ func EditPullRequest(ctx *context.APIContext) { err = issue_service.UpdateAssignees(ctx, issue, form.Assignee, form.Assignees, ctx.Doer) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Assignee does not exist: [name: %s]", err)) } else if errors.Is(err, user_model.ErrBlockedUser) { - ctx.Error(http.StatusForbidden, "UpdateAssignees", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "UpdateAssignees", err) + ctx.APIErrorInternal(err) } return } @@ -694,7 +694,7 @@ func EditPullRequest(ctx *context.APIContext) { oldMilestoneID := issue.MilestoneID issue.MilestoneID = form.Milestone if err = issue_service.ChangeMilestoneAssign(ctx, issue, ctx.Doer, oldMilestoneID); err != nil { - ctx.Error(http.StatusInternalServerError, "ChangeMilestoneAssign", err) + ctx.APIErrorInternal(err) return } } @@ -702,14 +702,14 @@ func EditPullRequest(ctx *context.APIContext) { if ctx.Repo.CanWrite(unit.TypePullRequests) && form.Labels != nil { labels, err := issues_model.GetLabelsInRepoByIDs(ctx, ctx.Repo.Repository.ID, form.Labels) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDsError", err) + ctx.APIErrorInternal(err) return } if ctx.Repo.Owner.IsOrganization() { orgLabels, err := issues_model.GetLabelsInOrgByIDs(ctx, ctx.Repo.Owner.ID, form.Labels) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelsInOrgByIDs", err) + ctx.APIErrorInternal(err) return } @@ -717,14 +717,14 @@ func EditPullRequest(ctx *context.APIContext) { } if err = issues_model.ReplaceIssueLabels(ctx, issue, labels, ctx.Doer); err != nil { - ctx.Error(http.StatusInternalServerError, "ReplaceLabelsError", err) + ctx.APIErrorInternal(err) return } } if form.State != nil { if pr.HasMerged { - ctx.Error(http.StatusPreconditionFailed, "MergedPRState", "cannot change state of this pull request, it was already merged") + ctx.APIError(http.StatusPreconditionFailed, "cannot change state of this pull request, it was already merged") return } @@ -738,21 +738,21 @@ func EditPullRequest(ctx *context.APIContext) { // change pull target branch if !pr.HasMerged && len(form.Base) != 0 && form.Base != pr.BaseBranch { if !ctx.Repo.GitRepo.IsBranchExist(form.Base) { - ctx.Error(http.StatusNotFound, "NewBaseBranchNotExist", fmt.Errorf("new base '%s' not exist", form.Base)) + ctx.APIError(http.StatusNotFound, fmt.Errorf("new base '%s' not exist", form.Base)) return } if err := pull_service.ChangeTargetBranch(ctx, pr, ctx.Doer, form.Base); err != nil { if issues_model.IsErrPullRequestAlreadyExists(err) { - ctx.Error(http.StatusConflict, "IsErrPullRequestAlreadyExists", err) + ctx.APIError(http.StatusConflict, err) return } else if issues_model.IsErrIssueIsClosed(err) { - ctx.Error(http.StatusUnprocessableEntity, "IsErrIssueIsClosed", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } else if pull_service.IsErrPullRequestHasMerged(err) { - ctx.Error(http.StatusConflict, "IsErrPullRequestHasMerged", err) + ctx.APIError(http.StatusConflict, err) return } - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } notify_service.PullRequestChangeTargetBranch(ctx, ctx.Doer, pr, form.Base) @@ -762,10 +762,10 @@ func EditPullRequest(ctx *context.APIContext) { if form.AllowMaintainerEdit != nil { if err := pull_service.SetAllowEdits(ctx, ctx.Doer, pr, *form.AllowMaintainerEdit); err != nil { if errors.Is(err, pull_service.ErrUserHasNoPermissionForAction) { - ctx.Error(http.StatusForbidden, "SetAllowEdits", fmt.Sprintf("SetAllowEdits: %s", err)) + ctx.APIError(http.StatusForbidden, fmt.Sprintf("SetAllowEdits: %s", err)) return } - ctx.ServerError("SetAllowEdits", err) + ctx.APIErrorInternal(err) return } } @@ -774,9 +774,9 @@ func EditPullRequest(ctx *context.APIContext) { pr, err = issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pr.Index) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -818,9 +818,9 @@ func IsPullRequestMerged(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -828,7 +828,7 @@ func IsPullRequestMerged(ctx *context.APIContext) { if pr.HasMerged { ctx.Status(http.StatusNoContent) } - ctx.NotFound() + ctx.APIErrorNotFound() } // MergePullRequest merges a PR given an index @@ -876,20 +876,20 @@ func MergePullRequest(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound("GetPullRequestByIndex", err) + ctx.APIErrorNotFound("GetPullRequestByIndex", err) } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } if err := pr.LoadHeadRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err) + ctx.APIErrorInternal(err) return } if err := pr.LoadIssue(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadIssue", err) + ctx.APIErrorInternal(err) return } pr.Issue.Repo = ctx.Repo.Repository @@ -897,7 +897,7 @@ func MergePullRequest(ctx *context.APIContext) { if ctx.IsSigned { // Update issue-user. if err = activities_model.SetIssueReadBy(ctx, pr.Issue.ID, ctx.Doer.ID); err != nil { - ctx.Error(http.StatusInternalServerError, "ReadBy", err) + ctx.APIErrorInternal(err) return } } @@ -915,21 +915,21 @@ func MergePullRequest(ctx *context.APIContext) { // start with merging by checking if err := pull_service.CheckPullMergeable(ctx, ctx.Doer, &ctx.Repo.Permission, pr, mergeCheckType, form.ForceMerge); err != nil { if errors.Is(err, pull_service.ErrIsClosed) { - ctx.NotFound() + ctx.APIErrorNotFound() } else if errors.Is(err, pull_service.ErrUserNotAllowedToMerge) { - ctx.Error(http.StatusMethodNotAllowed, "Merge", "User not allowed to merge PR") + ctx.APIError(http.StatusMethodNotAllowed, "User not allowed to merge PR") } else if errors.Is(err, pull_service.ErrHasMerged) { - ctx.Error(http.StatusMethodNotAllowed, "PR already merged", "") + ctx.APIError(http.StatusMethodNotAllowed, "") } else if errors.Is(err, pull_service.ErrIsWorkInProgress) { - ctx.Error(http.StatusMethodNotAllowed, "PR is a work in progress", "Work in progress PRs cannot be merged") + ctx.APIError(http.StatusMethodNotAllowed, "Work in progress PRs cannot be merged") } else if errors.Is(err, pull_service.ErrNotMergeableState) { - ctx.Error(http.StatusMethodNotAllowed, "PR not in mergeable state", "Please try again later") + ctx.APIError(http.StatusMethodNotAllowed, "Please try again later") } else if pull_service.IsErrDisallowedToMerge(err) { - ctx.Error(http.StatusMethodNotAllowed, "PR is not ready to be merged", err) + ctx.APIError(http.StatusMethodNotAllowed, err) } else if asymkey_service.IsErrWontSign(err) { - ctx.Error(http.StatusMethodNotAllowed, fmt.Sprintf("Protected branch %s requires signed commits but this merge would not be signed", pr.BaseBranch), err) + ctx.APIError(http.StatusMethodNotAllowed, err) } else { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) } return } @@ -938,14 +938,14 @@ 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.Error(http.StatusMethodNotAllowed, "Invalid merge style", fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do))) + ctx.APIError(http.StatusMethodNotAllowed, fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do))) return } if strings.Contains(err.Error(), "Wrong commit ID") { ctx.JSON(http.StatusConflict, err) return } - ctx.Error(http.StatusInternalServerError, "Manually-Merged", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusOK) @@ -960,7 +960,7 @@ func MergePullRequest(ctx *context.APIContext) { if len(message) == 0 { message, _, err = pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do)) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetDefaultMergeMessage", err) + ctx.APIErrorInternal(err) return } } @@ -974,10 +974,10 @@ func MergePullRequest(ctx *context.APIContext) { scheduled, err := automerge.ScheduleAutoMerge(ctx, ctx.Doer, pr, repo_model.MergeStyle(form.Do), message, form.DeleteBranchAfterMerge) if err != nil { if pull_model.IsErrAlreadyScheduledToAutoMerge(err) { - ctx.Error(http.StatusConflict, "ScheduleAutoMerge", err) + ctx.APIError(http.StatusConflict, err) return } - ctx.Error(http.StatusInternalServerError, "ScheduleAutoMerge", err) + ctx.APIErrorInternal(err) return } else if scheduled { // nothing more to do ... @@ -988,7 +988,7 @@ func MergePullRequest(ctx *context.APIContext) { if err := pull_service.Merge(ctx, pr, ctx.Doer, ctx.Repo.GitRepo, repo_model.MergeStyle(form.Do), form.HeadCommitID, message, false); err != nil { if pull_service.IsErrInvalidMergeStyle(err) { - ctx.Error(http.StatusMethodNotAllowed, "Invalid merge style", fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do))) + ctx.APIError(http.StatusMethodNotAllowed, fmt.Errorf("%s is not allowed an allowed merge style for this repository", repo_model.MergeStyle(form.Do))) } else if pull_service.IsErrMergeConflicts(err) { conflictError := err.(pull_service.ErrMergeConflicts) ctx.JSON(http.StatusConflict, conflictError) @@ -999,18 +999,18 @@ func MergePullRequest(ctx *context.APIContext) { conflictError := err.(pull_service.ErrMergeUnrelatedHistories) ctx.JSON(http.StatusConflict, conflictError) } else if git.IsErrPushOutOfDate(err) { - ctx.Error(http.StatusConflict, "Merge", "merge push out of date") + ctx.APIError(http.StatusConflict, "merge push out of date") } else if pull_service.IsErrSHADoesNotMatch(err) { - ctx.Error(http.StatusConflict, "Merge", "head out of date") + ctx.APIError(http.StatusConflict, "head out of date") } else if git.IsErrPushRejected(err) { errPushRej := err.(*git.ErrPushRejected) if len(errPushRej.Message) == 0 { - ctx.Error(http.StatusConflict, "Merge", "PushRejected without remote error message") + ctx.APIError(http.StatusConflict, "PushRejected without remote error message") } else { - ctx.Error(http.StatusConflict, "Merge", "PushRejected with remote message: "+errPushRej.Message) + ctx.APIError(http.StatusConflict, "PushRejected with remote message: "+errPushRej.Message) } } else { - ctx.Error(http.StatusInternalServerError, "Merge", err) + ctx.APIErrorInternal(err) } return } @@ -1024,7 +1024,7 @@ func MergePullRequest(ctx *context.APIContext) { // Don't cleanup when there are other PR's that use this branch as head branch. exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) if err != nil { - ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) + ctx.APIErrorInternal(err) return } if exist { @@ -1038,7 +1038,7 @@ func MergePullRequest(ctx *context.APIContext) { } else { headRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo) if err != nil { - ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.FullName()), err) + ctx.APIErrorInternal(err) return } defer headRepo.Close() @@ -1047,13 +1047,13 @@ func MergePullRequest(ctx *context.APIContext) { if err := repo_service.DeleteBranch(ctx, ctx.Doer, pr.HeadRepo, headRepo, pr.HeadBranch, pr); err != nil { switch { case git.IsErrBranchNotExist(err): - ctx.NotFound(err) + ctx.APIErrorNotFound(err) case errors.Is(err, repo_service.ErrBranchIsDefault): - ctx.Error(http.StatusForbidden, "DefaultBranch", fmt.Errorf("can not delete default branch")) + ctx.APIError(http.StatusForbidden, fmt.Errorf("can not delete default branch")) case errors.Is(err, git_model.ErrBranchIsProtected): - ctx.Error(http.StatusForbidden, "IsProtectedBranch", fmt.Errorf("branch protected")) + ctx.APIError(http.StatusForbidden, fmt.Errorf("branch protected")) default: - ctx.Error(http.StatusInternalServerError, "DeleteBranch", err) + ctx.APIErrorInternal(err) } return } @@ -1092,14 +1092,14 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) headUser, err = user_model.GetUserByName(ctx, headInfos[0]) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound("GetUserByName") + ctx.APIErrorNotFound("GetUserByName") } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return nil, nil } } else { - ctx.NotFound() + ctx.APIErrorNotFound() return nil, nil } @@ -1110,14 +1110,14 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) if headRepo == nil && !isSameRepo { err = baseRepo.GetBaseRepo(ctx) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetBaseRepo", err) + ctx.APIErrorInternal(err) return nil, nil } // Check if baseRepo's base repository is the same as headUser's repository. if baseRepo.BaseRepo == nil || baseRepo.BaseRepo.OwnerID != headUser.ID { log.Trace("parseCompareInfo[%d]: does not have fork or in same repository", baseRepo.ID) - ctx.NotFound("GetBaseRepo") + ctx.APIErrorNotFound("GetBaseRepo") return nil, nil } // Assign headRepo so it can be used below. @@ -1132,7 +1132,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) } else { headGitRepo, err = gitrepo.OpenRepository(ctx, headRepo) if err != nil { - ctx.Error(http.StatusInternalServerError, "OpenRepository", err) + ctx.APIErrorInternal(err) return nil, nil } closer = func() { _ = headGitRepo.Close() } @@ -1146,13 +1146,13 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) // user should have permission to read baseRepo's codes and pulls, NOT headRepo's permBase, err := access_model.GetUserRepoPermission(ctx, baseRepo, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return nil, nil } if !permBase.CanReadIssuesOrPulls(true) || !permBase.CanRead(unit.TypeCode) { log.Trace("Permission Denied: User %-v cannot create/read pull requests or cannot read code in Repo %-v\nUser in baseRepo has Permissions: %-+v", ctx.Doer, baseRepo, permBase) - ctx.NotFound("Can't read pulls or can't read UnitTypeCode") + ctx.APIErrorNotFound("Can't read pulls or can't read UnitTypeCode") return nil, nil } @@ -1160,12 +1160,12 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) // TODO: could the logic be simplified if the headRepo is the same as the baseRepo? Need to think more about it. permHead, err := access_model.GetUserRepoPermission(ctx, headRepo, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return nil, nil } if !permHead.CanRead(unit.TypeCode) { log.Trace("Permission Denied: User: %-v cannot read code in Repo: %-v\nUser in headRepo has Permissions: %-+v", ctx.Doer, headRepo, permHead) - ctx.NotFound("Can't read headRepo UnitTypeCode") + ctx.APIErrorNotFound("Can't read headRepo UnitTypeCode") return nil, nil } @@ -1178,13 +1178,13 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) headRefValid := headRef.IsBranch() || headRef.IsTag() || git.IsStringLikelyCommitID(git.ObjectFormatFromName(headRepo.ObjectFormatName), headRef.ShortName()) // Check if base&head ref are valid. if !baseRefValid || !headRefValid { - ctx.NotFound() + ctx.APIErrorNotFound() return nil, nil } compareInfo, err := headGitRepo.GetCompareInfo(repo_model.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseRef.ShortName(), headRef.ShortName(), false, false) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCompareInfo", err) + ctx.APIErrorInternal(err) return nil, nil } @@ -1236,34 +1236,34 @@ func UpdatePullRequest(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } if pr.HasMerged { - ctx.Error(http.StatusUnprocessableEntity, "UpdatePullRequest", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } if err = pr.LoadIssue(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadIssue", err) + ctx.APIErrorInternal(err) return } if pr.Issue.IsClosed { - ctx.Error(http.StatusUnprocessableEntity, "UpdatePullRequest", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } if err = pr.LoadBaseRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadBaseRepo", err) + ctx.APIErrorInternal(err) return } if err = pr.LoadHeadRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadHeadRepo", err) + ctx.APIErrorInternal(err) return } @@ -1271,7 +1271,7 @@ func UpdatePullRequest(ctx *context.APIContext) { allowedUpdateByMerge, allowedUpdateByRebase, err := pull_service.IsUserAllowedToUpdate(ctx, pr, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsUserAllowedToMerge", err) + ctx.APIErrorInternal(err) return } @@ -1285,13 +1285,13 @@ func UpdatePullRequest(ctx *context.APIContext) { if err = pull_service.Update(ctx, pr, ctx.Doer, message, rebase); err != nil { if pull_service.IsErrMergeConflicts(err) { - ctx.Error(http.StatusConflict, "Update", "merge failed because of conflict") + ctx.APIError(http.StatusConflict, "merge failed because of conflict") return } else if pull_service.IsErrRebaseConflicts(err) { - ctx.Error(http.StatusConflict, "Update", "rebase failed because of conflict") + ctx.APIError(http.StatusConflict, "rebase failed because of conflict") return } - ctx.Error(http.StatusInternalServerError, "pull_service.Update", err) + ctx.APIErrorInternal(err) return } @@ -1336,37 +1336,37 @@ func CancelScheduledAutoMerge(ctx *context.APIContext) { pull, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pullIndex) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return } - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } exist, autoMerge, err := pull_model.GetScheduledMergeByPullID(ctx, pull.ID) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if !exist { - ctx.NotFound() + ctx.APIErrorNotFound() return } if ctx.Doer.ID != autoMerge.DoerID { allowed, err := access_model.IsUserRepoAdmin(ctx, ctx.Repo.Repository, ctx.Doer) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if !allowed { - ctx.Error(http.StatusForbidden, "No permission to cancel", "user has no permission to cancel the scheduled auto merge") + ctx.APIError(http.StatusForbidden, "user has no permission to cancel the scheduled auto merge") return } } if err := automerge.RemoveScheduledAutoMerge(ctx, ctx.Doer, pull); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) } else { ctx.Status(http.StatusNoContent) } @@ -1421,22 +1421,22 @@ func GetPullRequestCommits(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } if err := pr.LoadBaseRepo(ctx); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } var prInfo *git.CompareInfo baseGitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.BaseRepo) if err != nil { - ctx.ServerError("OpenRepository", err) + ctx.APIErrorInternal(err) return } defer closer.Close() @@ -1447,7 +1447,7 @@ func GetPullRequestCommits(ctx *context.APIContext) { prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName(), false, false) } if err != nil { - ctx.ServerError("GetCompareInfo", err) + ctx.APIErrorInternal(err) return } commits := prInfo.Commits @@ -1476,7 +1476,7 @@ func GetPullRequestCommits(ctx *context.APIContext) { Files: files, }) if err != nil { - ctx.ServerError("toCommit", err) + ctx.APIErrorInternal(err) return } apiCommits = append(apiCommits, apiCommit) @@ -1544,20 +1544,20 @@ func GetPullRequestFiles(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } if err := pr.LoadBaseRepo(ctx); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if err := pr.LoadHeadRepo(ctx); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -1570,13 +1570,13 @@ func GetPullRequestFiles(ctx *context.APIContext) { prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitRefName(), true, false) } if err != nil { - ctx.ServerError("GetCompareInfo", err) + ctx.APIErrorInternal(err) return } headCommitID, err := baseGitRepo.GetRefCommitID(pr.GetGitRefName()) if err != nil { - ctx.ServerError("GetRefCommitID", err) + ctx.APIErrorInternal(err) return } @@ -1597,7 +1597,7 @@ func GetPullRequestFiles(ctx *context.APIContext) { WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.FormString("whitespace")), }) if err != nil { - ctx.ServerError("GetDiff", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index 6d7a326370c08..fb35126a99d72 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -64,20 +64,20 @@ func ListPullReviews(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound("GetPullRequestByIndex", err) + ctx.APIErrorNotFound("GetPullRequestByIndex", err) } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } if err = pr.LoadIssue(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadIssue", err) + ctx.APIErrorInternal(err) return } if err = pr.Issue.LoadRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadRepo", err) + ctx.APIErrorInternal(err) return } @@ -88,19 +88,19 @@ func ListPullReviews(ctx *context.APIContext) { allReviews, err := issues_model.FindReviews(ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } count, err := issues_model.CountReviews(ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } apiReviews, err := convert.ToPullReviewList(ctx, allReviews, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "convertToPullReviewList", err) + ctx.APIErrorInternal(err) return } @@ -151,7 +151,7 @@ func GetPullReview(ctx *context.APIContext) { apiReview, err := convert.ToPullReview(ctx, review, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "convertToPullReview", err) + ctx.APIErrorInternal(err) return } @@ -201,7 +201,7 @@ func GetPullReviewComments(ctx *context.APIContext) { apiComments, err := convert.ToPullReviewCommentList(ctx, review, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "convertToPullReviewCommentList", err) + ctx.APIErrorInternal(err) return } @@ -252,16 +252,16 @@ func DeletePullReview(ctx *context.APIContext) { } if ctx.Doer == nil { - ctx.NotFound() + ctx.APIErrorNotFound() return } if !ctx.Doer.IsAdmin && ctx.Doer.ID != review.ReviewerID { - ctx.Error(http.StatusForbidden, "only admin and user itself can delete a review", nil) + ctx.APIError(http.StatusForbidden, nil) return } if err := issues_model.DeleteReview(ctx, review); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteReview", fmt.Errorf("can not delete ReviewID: %d", review.ID)) + ctx.APIErrorInternal(fmt.Errorf("can not delete ReviewID: %d", review.ID)) return } @@ -309,9 +309,9 @@ func CreatePullReview(ctx *context.APIContext) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound("GetPullRequestByIndex", err) + ctx.APIErrorNotFound("GetPullRequestByIndex", err) } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } @@ -323,7 +323,7 @@ func CreatePullReview(ctx *context.APIContext) { } if err := pr.Issue.LoadRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "pr.Issue.LoadRepo", err) + ctx.APIErrorInternal(err) return } @@ -331,14 +331,14 @@ func CreatePullReview(ctx *context.APIContext) { if opts.CommitID == "" { gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.Issue.Repo) if err != nil { - ctx.Error(http.StatusInternalServerError, "git.OpenRepository", err) + ctx.APIErrorInternal(err) return } defer closer.Close() headCommitID, err := gitRepo.GetRefCommitID(pr.GetGitRefName()) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetRefCommitID", err) + ctx.APIErrorInternal(err) return } @@ -364,7 +364,7 @@ func CreatePullReview(ctx *context.APIContext) { opts.CommitID, nil, ); err != nil { - ctx.Error(http.StatusInternalServerError, "CreateCodeComment", err) + ctx.APIErrorInternal(err) return } } @@ -373,9 +373,9 @@ 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.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "SubmitReview", err) + ctx.APIErrorInternal(err) } return } @@ -383,7 +383,7 @@ func CreatePullReview(ctx *context.APIContext) { // convert response apiReview, err := convert.ToPullReview(ctx, review, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "convertToPullReview", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, apiReview) @@ -439,7 +439,7 @@ func SubmitPullReview(ctx *context.APIContext) { } if review.Type != issues_model.ReviewTypePending { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("only a pending review can be submitted")) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("only a pending review can be submitted")) return } @@ -451,13 +451,13 @@ func SubmitPullReview(ctx *context.APIContext) { // if review stay pending return if reviewType == issues_model.ReviewTypePending { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("review stay pending")) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("review stay pending")) return } headCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(pr.GetGitRefName()) if err != nil { - ctx.Error(http.StatusInternalServerError, "GitRepo: GetRefCommitID", err) + ctx.APIErrorInternal(err) return } @@ -465,9 +465,9 @@ 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.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "SubmitReview", err) + ctx.APIErrorInternal(err) } return } @@ -475,7 +475,7 @@ func SubmitPullReview(ctx *context.APIContext) { // convert response apiReview, err := convert.ToPullReview(ctx, review, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "convertToPullReview", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, apiReview) @@ -484,7 +484,7 @@ func SubmitPullReview(ctx *context.APIContext) { // preparePullReviewType return ReviewType and false or nil and true if an error happen func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest, event api.ReviewStateType, body string, hasComments bool) (issues_model.ReviewType, bool) { if err := pr.LoadIssue(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadIssue", err) + ctx.APIErrorInternal(err) return -1, true } @@ -496,7 +496,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.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("approve your own pull is not allowed")) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("approve your own pull is not allowed")) return -1, true } reviewType = issues_model.ReviewTypeApprove @@ -505,7 +505,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.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("reject your own pull is not allowed")) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("reject your own pull is not allowed")) return -1, true } reviewType = issues_model.ReviewTypeReject @@ -515,7 +515,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.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("review event %s requires a body or a comment", event)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("review event %s requires a body or a comment", event)) return -1, true } default: @@ -524,7 +524,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.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("review event %s requires a body", event)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("review event %s requires a body", event)) return -1, true } @@ -536,9 +536,9 @@ func prepareSingleReview(ctx *context.APIContext) (*issues_model.Review, *issues pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound("GetPullRequestByIndex", err) + ctx.APIErrorNotFound("GetPullRequestByIndex", err) } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return nil, nil, true } @@ -546,27 +546,27 @@ func prepareSingleReview(ctx *context.APIContext) (*issues_model.Review, *issues review, err := issues_model.GetReviewByID(ctx, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrReviewNotExist(err) { - ctx.NotFound("GetReviewByID", err) + ctx.APIErrorNotFound("GetReviewByID", err) } else { - ctx.Error(http.StatusInternalServerError, "GetReviewByID", err) + ctx.APIErrorInternal(err) } return nil, nil, true } // validate the review is for the given PR if review.IssueID != pr.IssueID { - ctx.NotFound("ReviewNotInPR") + ctx.APIErrorNotFound("ReviewNotInPR") return nil, nil, true } // make sure that the user has access to this review if it is pending if review.Type == issues_model.ReviewTypePending && review.ReviewerID != ctx.Doer.ID && !ctx.Doer.IsAdmin { - ctx.NotFound("GetReviewByID") + ctx.APIErrorNotFound("GetReviewByID") return nil, nil, true } if err := review.LoadAttributes(ctx); err != nil && !user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusInternalServerError, "ReviewLoadAttributes", err) + ctx.APIErrorInternal(err) return nil, nil, true } @@ -668,10 +668,10 @@ func parseReviewersByNames(ctx *context.APIContext, reviewerNames, teamReviewerN if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound("UserNotExist", fmt.Sprintf("User '%s' not exist", r)) + ctx.APIErrorNotFound("UserNotExist", fmt.Sprintf("User '%s' not exist", r)) return nil, nil } - ctx.Error(http.StatusInternalServerError, "GetUser", err) + ctx.APIErrorInternal(err) return nil, nil } @@ -684,10 +684,10 @@ func parseReviewersByNames(ctx *context.APIContext, reviewerNames, teamReviewerN teamReviewer, err = organization.GetTeam(ctx, ctx.Repo.Owner.ID, t) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.NotFound("TeamNotExist", fmt.Sprintf("Team '%s' not exist", t)) + ctx.APIErrorNotFound("TeamNotExist", fmt.Sprintf("Team '%s' not exist", t)) return nil, nil } - ctx.Error(http.StatusInternalServerError, "ReviewRequest", err) + ctx.APIErrorInternal(err) return nil, nil } @@ -701,21 +701,21 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound("GetPullRequestByIndex", err) + ctx.APIErrorNotFound("GetPullRequestByIndex", err) } else { - ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) + ctx.APIErrorInternal(err) } return } if err := pr.Issue.LoadRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "pr.Issue.LoadRepo", err) + ctx.APIErrorInternal(err) return } permDoer, err := access_model.GetUserRepoPermission(ctx, pr.Issue.Repo, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return } @@ -733,20 +733,20 @@ 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.Error(http.StatusForbidden, "", err) + ctx.APIError(http.StatusForbidden, err) return } if issues_model.IsErrNotValidReviewRequest(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "ReviewRequest", err) + ctx.APIErrorInternal(err) return } if comment != nil && isAdd { if err = comment.LoadReview(ctx); err != nil { - ctx.ServerError("ReviewRequest", err) + ctx.APIErrorInternal(err) return } reviews = append(reviews, comment.Review) @@ -758,20 +758,20 @@ 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.Error(http.StatusForbidden, "", err) + ctx.APIError(http.StatusForbidden, err) return } if issues_model.IsErrNotValidReviewRequest(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.ServerError("TeamReviewRequest", err) + ctx.APIErrorInternal(err) return } if comment != nil && isAdd { if err = comment.LoadReview(ctx); err != nil { - ctx.ServerError("ReviewRequest", err) + ctx.APIErrorInternal(err) return } reviews = append(reviews, comment.Review) @@ -782,7 +782,7 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions if isAdd { apiReviews, err := convert.ToPullReviewList(ctx, reviews, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "convertToPullReviewList", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusCreated, apiReviews) @@ -884,7 +884,7 @@ func UnDismissPullReview(ctx *context.APIContext) { func dismissReview(ctx *context.APIContext, msg string, isDismiss, dismissPriors bool) { if !ctx.Repo.IsAdmin() { - ctx.Error(http.StatusForbidden, "", "Must be repo admin") + ctx.APIError(http.StatusForbidden, "Must be repo admin") return } review, _, isWrong := prepareSingleReview(ctx) @@ -893,29 +893,29 @@ func dismissReview(ctx *context.APIContext, msg string, isDismiss, dismissPriors } if review.Type != issues_model.ReviewTypeApprove && review.Type != issues_model.ReviewTypeReject { - ctx.Error(http.StatusForbidden, "", "not need to dismiss this review because it's type is not Approve or change request") + ctx.APIError(http.StatusForbidden, "not need to dismiss this review because it's type is not Approve or change request") return } _, err := pull_service.DismissReview(ctx, review.ID, ctx.Repo.Repository.ID, msg, ctx.Doer, isDismiss, dismissPriors) if err != nil { if pull_service.IsErrDismissRequestOnClosedPR(err) { - ctx.Error(http.StatusForbidden, "", err) + ctx.APIError(http.StatusForbidden, err) return } - ctx.Error(http.StatusInternalServerError, "pull_service.DismissReview", err) + ctx.APIErrorInternal(err) return } if review, err = issues_model.GetReviewByID(ctx, review.ID); err != nil { - ctx.Error(http.StatusInternalServerError, "GetReviewByID", err) + ctx.APIErrorInternal(err) return } // convert response apiReview, err := convert.ToPullReview(ctx, review, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "convertToPullReview", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, apiReview) diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 076f00f1d1429..36fff126e1e7d 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -53,16 +53,16 @@ func GetRelease(ctx *context.APIContext) { id := ctx.PathParamInt64("id") release, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id) if err != nil && !repo_model.IsErrReleaseNotExist(err) { - ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err) + ctx.APIErrorInternal(err) return } if err != nil && repo_model.IsErrReleaseNotExist(err) || release.IsTag { - ctx.NotFound() + ctx.APIErrorNotFound() return } if err := release.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToAPIRelease(ctx, ctx.Repo.Repository, release)) @@ -93,17 +93,17 @@ func GetLatestRelease(ctx *context.APIContext) { // "$ref": "#/responses/notFound" release, err := repo_model.GetLatestReleaseByRepoID(ctx, ctx.Repo.Repository.ID) if err != nil && !repo_model.IsErrReleaseNotExist(err) { - ctx.Error(http.StatusInternalServerError, "GetLatestRelease", err) + ctx.APIErrorInternal(err) return } if err != nil && repo_model.IsErrReleaseNotExist(err) || release.IsTag || release.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } if err := release.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToAPIRelease(ctx, ctx.Repo.Repository, release)) @@ -161,13 +161,13 @@ func ListReleases(ctx *context.APIContext) { releases, err := db.Find[repo_model.Release](ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetReleasesByRepoID", err) + ctx.APIErrorInternal(err) return } rels := make([]*api.Release, len(releases)) for i, release := range releases { if err := release.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } rels[i] = convert.ToAPIRelease(ctx, ctx.Repo.Repository, release) @@ -175,7 +175,7 @@ func ListReleases(ctx *context.APIContext) { filteredCount, err := db.Count[repo_model.Release](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -220,13 +220,13 @@ func CreateRelease(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.CreateReleaseOption) if ctx.Repo.Repository.IsEmpty { - ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty")) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("repo is empty")) return } rel, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, form.TagName) if err != nil { if !repo_model.IsErrReleaseNotExist(err) { - ctx.Error(http.StatusInternalServerError, "GetRelease", err) + ctx.APIErrorInternal(err) return } // If target is not provided use default branch @@ -248,19 +248,19 @@ func CreateRelease(ctx *context.APIContext) { } if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, nil, ""); err != nil { if repo_model.IsErrReleaseAlreadyExist(err) { - ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err) + ctx.APIError(http.StatusConflict, err) } else if release_service.IsErrProtectedTagName(err) { - ctx.Error(http.StatusUnprocessableEntity, "ProtectedTagName", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else if git.IsErrNotExist(err) { - ctx.Error(http.StatusNotFound, "ErrNotExist", fmt.Errorf("target \"%v\" not found: %w", rel.Target, err)) + ctx.APIError(http.StatusNotFound, fmt.Errorf("target \"%v\" not found: %w", rel.Target, err)) } else { - ctx.Error(http.StatusInternalServerError, "CreateRelease", err) + ctx.APIErrorInternal(err) } return } } else { if !rel.IsTag { - ctx.Error(http.StatusConflict, "GetRelease", "Release is has no Tag") + ctx.APIError(http.StatusConflict, "Release is has no Tag") return } @@ -275,7 +275,7 @@ func CreateRelease(ctx *context.APIContext) { rel.Target = form.Target if err = release_service.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo, rel, nil, nil, nil); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateRelease", err) + ctx.APIErrorInternal(err) return } } @@ -322,11 +322,11 @@ func EditRelease(ctx *context.APIContext) { id := ctx.PathParamInt64("id") rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id) if err != nil && !repo_model.IsErrReleaseNotExist(err) { - ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err) + ctx.APIErrorInternal(err) return } if err != nil && repo_model.IsErrReleaseNotExist(err) || rel.IsTag { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -349,18 +349,18 @@ func EditRelease(ctx *context.APIContext) { rel.IsPrerelease = *form.IsPrerelease } if err := release_service.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo, rel, nil, nil, nil); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateRelease", err) + ctx.APIErrorInternal(err) return } // reload data from database rel, err = repo_model.GetReleaseByID(ctx, id) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) + ctx.APIErrorInternal(err) return } if err := rel.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToAPIRelease(ctx, ctx.Repo.Repository, rel)) @@ -399,19 +399,19 @@ func DeleteRelease(ctx *context.APIContext) { id := ctx.PathParamInt64("id") rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id) if err != nil && !repo_model.IsErrReleaseNotExist(err) { - ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err) + ctx.APIErrorInternal(err) return } if err != nil && repo_model.IsErrReleaseNotExist(err) || rel.IsTag { - ctx.NotFound() + ctx.APIErrorNotFound() return } if err := release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, rel, ctx.Doer, false); err != nil { if release_service.IsErrProtectedTagName(err) { - ctx.Error(http.StatusUnprocessableEntity, "delTag", "user not allowed to delete protected tag") + ctx.APIError(http.StatusUnprocessableEntity, "user not allowed to delete protected tag") return } - ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index 54ca1fc8431d1..defde81a1d2ae 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -23,14 +23,14 @@ func checkReleaseMatchRepo(ctx *context.APIContext, releaseID int64) bool { release, err := repo_model.GetReleaseByID(ctx, releaseID) if err != nil { if repo_model.IsErrReleaseNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return false } - ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) + ctx.APIErrorInternal(err) return false } if release.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return false } return true @@ -81,15 +81,15 @@ func GetReleaseAttachment(ctx *context.APIContext) { attach, err := repo_model.GetAttachmentByID(ctx, attachID) if err != nil { if repo_model.IsErrAttachmentNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return } - ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) + ctx.APIErrorInternal(err) return } if attach.ReleaseID != releaseID { log.Info("User requested attachment is not in release, release_id %v, attachment_id: %v", releaseID, attachID) - ctx.NotFound() + ctx.APIErrorNotFound() return } // FIXME Should prove the existence of the given repo, but results in unnecessary database requests @@ -130,18 +130,18 @@ func ListReleaseAttachments(ctx *context.APIContext) { release, err := repo_model.GetReleaseByID(ctx, releaseID) if err != nil { if repo_model.IsErrReleaseNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return } - ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) + ctx.APIErrorInternal(err) return } if release.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } if err := release.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToAPIRelease(ctx, ctx.Repo.Repository, release).Attachments) @@ -194,7 +194,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) { // Check if attachments are enabled if !setting.Attachment.Enabled { - ctx.NotFound("Attachment is not enabled") + ctx.APIErrorNotFound("Attachment is not enabled") return } @@ -212,7 +212,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) { if strings.HasPrefix(strings.ToLower(ctx.Req.Header.Get("Content-Type")), "multipart/form-data") { file, header, err := ctx.Req.FormFile("attachment") if err != nil { - ctx.Error(http.StatusInternalServerError, "GetFile", err) + ctx.APIErrorInternal(err) return } defer file.Close() @@ -229,7 +229,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) { } if filename == "" { - ctx.Error(http.StatusBadRequest, "CreateReleaseAttachment", "Could not determine name of attachment.") + ctx.APIError(http.StatusBadRequest, "Could not determine name of attachment.") return } @@ -242,10 +242,10 @@ func CreateReleaseAttachment(ctx *context.APIContext) { }) if err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.Error(http.StatusBadRequest, "DetectContentType", err) + ctx.APIError(http.StatusBadRequest, err) return } - ctx.Error(http.StatusInternalServerError, "NewAttachment", err) + ctx.APIErrorInternal(err) return } @@ -308,15 +308,15 @@ func EditReleaseAttachment(ctx *context.APIContext) { attach, err := repo_model.GetAttachmentByID(ctx, attachID) if err != nil { if repo_model.IsErrAttachmentNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return } - ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) + ctx.APIErrorInternal(err) return } if attach.ReleaseID != releaseID { log.Info("User requested attachment is not in release, release_id %v, attachment_id: %v", releaseID, attachID) - ctx.NotFound() + ctx.APIErrorNotFound() return } // FIXME Should prove the existence of the given repo, but results in unnecessary database requests @@ -326,10 +326,10 @@ func EditReleaseAttachment(ctx *context.APIContext) { if err := attachment_service.UpdateAttachment(ctx, setting.Repository.Release.AllowedTypes, attach); err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attach)) @@ -381,21 +381,21 @@ func DeleteReleaseAttachment(ctx *context.APIContext) { attach, err := repo_model.GetAttachmentByID(ctx, attachID) if err != nil { if repo_model.IsErrAttachmentNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return } - ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) + ctx.APIErrorInternal(err) return } if attach.ReleaseID != releaseID { log.Info("User requested attachment is not in release, release_id %v, attachment_id: %v", releaseID, attachID) - ctx.NotFound() + ctx.APIErrorNotFound() return } // FIXME Should prove the existence of the given repo, but results in unnecessary database requests if err := repo_model.DeleteAttachment(ctx, attach, true); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteAttachment", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go index 7380c5231c55c..b5e7d83b2adcf 100644 --- a/routers/api/v1/repo/release_tags.go +++ b/routers/api/v1/repo/release_tags.go @@ -46,20 +46,20 @@ func GetReleaseByTag(ctx *context.APIContext) { release, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, tag) if err != nil { if repo_model.IsErrReleaseNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return } - ctx.Error(http.StatusInternalServerError, "GetRelease", err) + ctx.APIErrorInternal(err) return } if release.IsTag { - ctx.NotFound() + ctx.APIErrorNotFound() return } if err = release.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToAPIRelease(ctx, ctx.Repo.Repository, release)) @@ -99,24 +99,24 @@ func DeleteReleaseByTag(ctx *context.APIContext) { release, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, tag) if err != nil { if repo_model.IsErrReleaseNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return } - ctx.Error(http.StatusInternalServerError, "GetRelease", err) + ctx.APIErrorInternal(err) return } if release.IsTag { - ctx.NotFound() + ctx.APIErrorNotFound() return } if err = release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, release, ctx.Doer, false); err != nil { if release_service.IsErrProtectedTagName(err) { - ctx.Error(http.StatusUnprocessableEntity, "delTag", "user not allowed to delete protected tag") + ctx.APIError(http.StatusUnprocessableEntity, "user not allowed to delete protected tag") return } - ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index ce09e7fc0f9bd..d418b8e4b5b6a 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -171,7 +171,7 @@ func Search(ctx *context.APIContext) { opts.Collaborate = optional.Some(true) case "": default: - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid search mode: \"%s\"", mode)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid search mode: \"%s\"", mode)) return } @@ -193,11 +193,11 @@ func Search(ctx *context.APIContext) { if orderBy, ok := searchModeMap[sortMode]; ok { opts.OrderBy = orderBy } else { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid sort mode: \"%s\"", sortMode)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid sort mode: \"%s\"", sortMode)) return } } else { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid sort order: \"%s\"", sortOrder)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("Invalid sort order: \"%s\"", sortOrder)) return } } @@ -245,7 +245,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.Error(http.StatusBadRequest, "", fmt.Errorf("readme template does not exist, available templates: %v", repo_module.Readmes)) + ctx.APIError(http.StatusBadRequest, fmt.Errorf("readme template does not exist, available templates: %v", repo_module.Readmes)) return } @@ -265,13 +265,13 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre }) if err != nil { if repo_model.IsErrRepoAlreadyExist(err) { - ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.") + ctx.APIError(http.StatusConflict, "The repository with the same name already exists.") } else if db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || label.IsErrTemplateLoad(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateRepository", err) + ctx.APIErrorInternal(err) } return } @@ -279,7 +279,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre // reload repo from db to get a real state after creation repo, err = repo_model.GetRepositoryByID(ctx, repo.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetRepositoryByID", err) + ctx.APIErrorInternal(err) } ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeOwner})) @@ -311,7 +311,7 @@ func Create(ctx *context.APIContext) { opt := web.GetForm(ctx).(*api.CreateRepoOption) if ctx.Doer.IsOrganization() { // Shouldn't reach this condition, but just in case. - ctx.Error(http.StatusUnprocessableEntity, "", "not allowed creating repository for organization") + ctx.APIError(http.StatusUnprocessableEntity, "not allowed creating repository for organization") return } CreateUserRepo(ctx, ctx.Doer, *opt) @@ -355,12 +355,12 @@ func Generate(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.GenerateRepoOption) if !ctx.Repo.Repository.IsTemplate { - ctx.Error(http.StatusUnprocessableEntity, "", "this is not a template repo") + ctx.APIError(http.StatusUnprocessableEntity, "this is not a template repo") return } if ctx.Doer.IsOrganization() { - ctx.Error(http.StatusUnprocessableEntity, "", "not allowed creating repository for organization") + ctx.APIError(http.StatusUnprocessableEntity, "not allowed creating repository for organization") return } @@ -379,7 +379,7 @@ func Generate(ctx *context.APIContext) { } if !opts.IsValid() { - ctx.Error(http.StatusUnprocessableEntity, "", "must select at least one template item") + ctx.APIError(http.StatusUnprocessableEntity, "must select at least one template item") return } @@ -395,22 +395,22 @@ func Generate(ctx *context.APIContext) { return } - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) return } if !ctx.Doer.IsAdmin && !ctxUser.IsOrganization() { - ctx.Error(http.StatusForbidden, "", "Only admin can generate repository for other user.") + ctx.APIError(http.StatusForbidden, "Only admin can generate repository for other user.") return } if !ctx.Doer.IsAdmin { canCreate, err := organization.OrgFromUser(ctxUser).CanCreateOrgRepo(ctx, ctx.Doer.ID) if err != nil { - ctx.ServerError("CanCreateOrgRepo", err) + ctx.APIErrorInternal(err) return } else if !canCreate { - ctx.Error(http.StatusForbidden, "", "Given user is not allowed to create repository in organization.") + ctx.APIError(http.StatusForbidden, "Given user is not allowed to create repository in organization.") return } } @@ -419,12 +419,12 @@ func Generate(ctx *context.APIContext) { repo, err := repo_service.GenerateRepository(ctx, ctx.Doer, ctxUser, ctx.Repo.Repository, opts) if err != nil { if repo_model.IsErrRepoAlreadyExist(err) { - ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.") + ctx.APIError(http.StatusConflict, "The repository with the same name already exists.") } else if db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateRepository", err) + ctx.APIErrorInternal(err) } return } @@ -498,25 +498,25 @@ func CreateOrgRepo(ctx *context.APIContext) { org, err := organization.GetOrgByName(ctx, ctx.PathParam("org")) if err != nil { if organization.IsErrOrgNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "", err) + ctx.APIError(http.StatusUnprocessableEntity, err) } else { - ctx.Error(http.StatusInternalServerError, "GetOrgByName", err) + ctx.APIErrorInternal(err) } return } if !organization.HasOrgOrUserVisible(ctx, org.AsUser(), ctx.Doer) { - ctx.NotFound("HasOrgOrUserVisible", nil) + ctx.APIErrorNotFound("HasOrgOrUserVisible", nil) return } if !ctx.Doer.IsAdmin { canCreate, err := org.CanCreateOrgRepo(ctx, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "CanCreateOrgRepo", err) + ctx.APIErrorInternal(err) return } else if !canCreate { - ctx.Error(http.StatusForbidden, "", "Given user is not allowed to create repository in organization.") + ctx.APIError(http.StatusForbidden, "Given user is not allowed to create repository in organization.") return } } @@ -548,7 +548,7 @@ func Get(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if err := ctx.Repo.Repository.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "Repository.LoadAttributes", err) + ctx.APIErrorInternal(err) return } @@ -578,19 +578,19 @@ func GetByID(ctx *context.APIContext) { repo, err := repo_model.GetRepositoryByID(ctx, ctx.PathParamInt64("id")) if err != nil { if repo_model.IsErrRepoNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetRepositoryByID", err) + ctx.APIErrorInternal(err) } return } permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return } else if !permission.HasAnyUnitAccess() { - ctx.NotFound() + ctx.APIErrorNotFound() return } ctx.JSON(http.StatusOK, convert.ToRepo(ctx, repo, permission)) @@ -653,7 +653,7 @@ func Edit(ctx *context.APIContext) { repo, err := repo_model.GetRepositoryByID(ctx, ctx.Repo.Repository.ID) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -673,13 +673,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.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is already taken [name: %s]", newRepoName), err) + ctx.APIError(http.StatusUnprocessableEntity, err) case db.IsErrNameReserved(err): - ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is reserved [name: %s]", newRepoName), err) + ctx.APIError(http.StatusUnprocessableEntity, err) case db.IsErrNamePatternNotAllowed(err): - ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name's pattern is not allowed [name: %s, pattern: %s]", newRepoName, err.(db.ErrNamePatternNotAllowed).Pattern), err) + ctx.APIError(http.StatusUnprocessableEntity, err) default: - ctx.Error(http.StatusUnprocessableEntity, "ChangeRepositoryName", err) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("ChangeRepositoryName: %w", err)) } return err } @@ -703,7 +703,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err // Visibility of forked repository is forced sync with base repository. if repo.IsFork { if err := repo.GetBaseRepo(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "Unable to load base repository", err) + ctx.APIErrorInternal(err) return err } *opts.Private = repo.BaseRepo.IsPrivate @@ -713,7 +713,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 := fmt.Errorf("cannot change private repository to public") - ctx.Error(http.StatusUnprocessableEntity, "Force Private enabled", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return err } @@ -728,7 +728,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err var err error ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, repo) if err != nil { - ctx.Error(http.StatusInternalServerError, "Unable to OpenRepository", err) + ctx.APIErrorInternal(err) return err } } @@ -738,7 +738,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err if opts.DefaultBranch != nil && repo.DefaultBranch != *opts.DefaultBranch && (repo.IsEmpty || ctx.Repo.GitRepo.IsBranchExist(*opts.DefaultBranch)) { if !repo.IsEmpty { if err := gitrepo.SetDefaultBranch(ctx, ctx.Repo.Repository, *opts.DefaultBranch); err != nil { - ctx.Error(http.StatusInternalServerError, "SetDefaultBranch", err) + ctx.APIErrorInternal(err) return err } updateRepoLicense = true @@ -747,7 +747,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err } if err := repo_service.UpdateRepository(ctx, repo, visibilityChanged); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateRepository", err) + ctx.APIErrorInternal(err) return err } @@ -755,7 +755,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err if err := repo_service.AddRepoToLicenseUpdaterQueue(&repo_service.LicenseUpdaterOptions{ RepoID: ctx.Repo.Repository.ID, }); err != nil { - ctx.Error(http.StatusInternalServerError, "AddRepoToLicenseUpdaterQueue", err) + ctx.APIErrorInternal(err) return err } } @@ -782,12 +782,12 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { // Check that values are valid if !validation.IsValidExternalURL(opts.ExternalTracker.ExternalTrackerURL) { err := fmt.Errorf("External tracker URL not valid") - ctx.Error(http.StatusUnprocessableEntity, "Invalid external tracker URL", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return err } if len(opts.ExternalTracker.ExternalTrackerFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(opts.ExternalTracker.ExternalTrackerFormat) { err := fmt.Errorf("External tracker URL format not valid") - ctx.Error(http.StatusUnprocessableEntity, "Invalid external tracker URL format", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return err } @@ -849,7 +849,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { // Check that values are valid if !validation.IsValidExternalURL(opts.ExternalWiki.ExternalWikiURL) { err := fmt.Errorf("External wiki URL not valid") - ctx.Error(http.StatusUnprocessableEntity, "", "Invalid external wiki URL") + ctx.APIError(http.StatusUnprocessableEntity, "Invalid external wiki URL") return err } @@ -1024,7 +1024,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { if len(units)+len(deleteUnitTypes) > 0 { if err := repo_service.UpdateRepositoryUnits(ctx, repo, units, deleteUnitTypes); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateRepositoryUnits", err) + ctx.APIErrorInternal(err) return err } } @@ -1040,13 +1040,13 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e if opts.Archived != nil { if repo.IsMirror { err := fmt.Errorf("repo is a mirror, cannot archive/un-archive") - ctx.Error(http.StatusUnprocessableEntity, err.Error(), err) + ctx.APIError(http.StatusUnprocessableEntity, err) return err } if *opts.Archived { if err := repo_model.SetArchiveRepoState(ctx, repo, *opts.Archived); err != nil { log.Error("Tried to archive a repo: %s", err) - ctx.Error(http.StatusInternalServerError, "ArchiveRepoState", err) + ctx.APIErrorInternal(err) return err } if err := actions_model.CleanRepoScheduleTasks(ctx, repo); err != nil { @@ -1056,7 +1056,7 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e } else { if err := repo_model.SetArchiveRepoState(ctx, repo, *opts.Archived); err != nil { log.Error("Tried to un-archive a repo: %s", err) - ctx.Error(http.StatusInternalServerError, "ArchiveRepoState", err) + ctx.APIErrorInternal(err) return err } if ctx.Repo.Repository.UnitEnabled(ctx, unit_model.TypeActions) { @@ -1084,7 +1084,7 @@ func updateMirror(ctx *context.APIContext, opts api.EditRepoOption) error { mirror, err := repo_model.GetMirrorByRepoID(ctx, repo.ID) if err != nil { log.Error("Failed to get mirror: %s", err) - ctx.Error(http.StatusInternalServerError, "MirrorInterval", err) + ctx.APIErrorInternal(err) return err } @@ -1094,14 +1094,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.Error(http.StatusUnprocessableEntity, "MirrorInterval", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return err } // Ensure the provided duration is not too short if interval != 0 && interval < setting.Mirror.MinInterval { err := fmt.Errorf("invalid mirror interval: %s is below minimum interval: %s", interval, setting.Mirror.MinInterval) - ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return err } @@ -1120,7 +1120,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.Error(http.StatusUnprocessableEntity, "MirrorInterval", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return err } @@ -1158,10 +1158,10 @@ func Delete(ctx *context.APIContext) { canDelete, err := repo_module.CanUserDelete(ctx, repo, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "CanUserDelete", err) + ctx.APIErrorInternal(err) return } else if !canDelete { - ctx.Error(http.StatusForbidden, "", "Given user is not owner of organization.") + ctx.APIError(http.StatusForbidden, "Given user is not owner of organization.") return } @@ -1170,7 +1170,7 @@ func Delete(ctx *context.APIContext) { } if err := repo_service.DeleteRepository(ctx, ctx.Doer, repo, true); err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteRepository", err) + ctx.APIErrorInternal(err) return } @@ -1315,7 +1315,7 @@ func ListRepoActivityFeeds(ctx *context.APIContext) { feeds, count, err := feed_service.GetFeeds(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetFeeds", err) + ctx.APIErrorInternal(err) return } ctx.SetTotalCountHeader(count) diff --git a/routers/api/v1/repo/star.go b/routers/api/v1/repo/star.go index 46ed17ad91eb6..46218e0e283de 100644 --- a/routers/api/v1/repo/star.go +++ b/routers/api/v1/repo/star.go @@ -49,7 +49,7 @@ func ListStargazers(ctx *context.APIContext) { stargazers, err := repo_model.GetStargazers(ctx, ctx.Repo.Repository, utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetStargazers", err) + ctx.APIErrorInternal(err) return } users := make([]*api.User, len(stargazers)) diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index 8c910a68f9098..e1dbb25865d79 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.Error(http.StatusBadRequest, "sha not given", nil) + ctx.APIError(http.StatusBadRequest, nil) return } status := &git_model.CommitStatus{ @@ -65,7 +65,7 @@ func NewCommitStatus(ctx *context.APIContext) { Context: form.Context, } if err := commitstatus_service.CreateCommitStatus(ctx, ctx.Repo.Repository, ctx.Doer, sha, status); err != nil { - ctx.Error(http.StatusInternalServerError, "CreateCommitStatus", err) + ctx.APIErrorInternal(err) return } @@ -187,7 +187,7 @@ func GetCommitStatusesByRef(ctx *context.APIContext) { func getCommitStatuses(ctx *context.APIContext, sha string) { if len(sha) == 0 { - ctx.Error(http.StatusBadRequest, "ref/sha not given", nil) + ctx.APIError(http.StatusBadRequest, nil) return } sha = utils.MustConvertToSHA1(ctx.Base, ctx.Repo, sha) @@ -203,7 +203,7 @@ func getCommitStatuses(ctx *context.APIContext, sha string) { State: ctx.FormTrim("state"), }) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommitStatuses", fmt.Errorf("GetCommitStatuses[%s, %s, %d]: %w", repo.FullName(), sha, ctx.FormInt("page"), err)) + ctx.APIErrorInternal(fmt.Errorf("GetCommitStatuses[%s, %s, %d]: %w", repo.FullName(), sha, ctx.FormInt("page"), err)) return } @@ -266,7 +266,7 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) { statuses, count, err := git_model.GetLatestCommitStatus(ctx, repo.ID, sha, utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLatestCommitStatus", fmt.Errorf("GetLatestCommitStatus[%s, %s]: %w", repo.FullName(), sha, err)) + ctx.APIErrorInternal(fmt.Errorf("GetLatestCommitStatus[%s, %s]: %w", repo.FullName(), sha, err)) return } diff --git a/routers/api/v1/repo/subscriber.go b/routers/api/v1/repo/subscriber.go index 8584182857825..14f296a83d257 100644 --- a/routers/api/v1/repo/subscriber.go +++ b/routers/api/v1/repo/subscriber.go @@ -47,7 +47,7 @@ func ListSubscribers(ctx *context.APIContext) { subscribers, err := repo_model.GetRepoWatchers(ctx, ctx.Repo.Repository.ID, utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetRepoWatchers", err) + ctx.APIErrorInternal(err) return } users := make([]*api.User, len(subscribers)) diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index 8447a8f1f223e..2e6c1c1023552 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -57,7 +57,7 @@ func ListTags(ctx *context.APIContext) { tags, total, err := ctx.Repo.GitRepo.GetTagInfos(listOpts.Page, listOpts.PageSize) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetTags", err) + ctx.APIErrorInternal(err) return } @@ -103,16 +103,16 @@ func GetAnnotatedTag(ctx *context.APIContext) { sha := ctx.PathParam("sha") if len(sha) == 0 { - ctx.Error(http.StatusBadRequest, "", "SHA not provided") + ctx.APIError(http.StatusBadRequest, "SHA not provided") return } if tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha); err != nil { - ctx.Error(http.StatusBadRequest, "GetAnnotatedTag", err) + ctx.APIError(http.StatusBadRequest, err) } else { commit, err := tag.Commit(ctx.Repo.GitRepo) if err != nil { - ctx.Error(http.StatusBadRequest, "GetAnnotatedTag", err) + ctx.APIError(http.StatusBadRequest, err) } ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx, ctx.Repo.Repository, tag, commit)) } @@ -150,7 +150,7 @@ func GetTag(ctx *context.APIContext) { tag, err := ctx.Repo.GitRepo.GetTag(tagName) if err != nil { - ctx.NotFound(tagName) + ctx.APIErrorNotFound(tagName) return } ctx.JSON(http.StatusOK, convert.ToTag(ctx.Repo.Repository, tag)) @@ -200,27 +200,27 @@ func CreateTag(ctx *context.APIContext) { commit, err := ctx.Repo.GitRepo.GetCommit(form.Target) if err != nil { - ctx.Error(http.StatusNotFound, "target not found", fmt.Errorf("target not found: %w", err)) + ctx.APIError(http.StatusNotFound, fmt.Errorf("target not found: %w", err)) return } if err := release_service.CreateNewTag(ctx, ctx.Doer, ctx.Repo.Repository, commit.ID.String(), form.TagName, form.Message); err != nil { if release_service.IsErrTagAlreadyExists(err) { - ctx.Error(http.StatusConflict, "tag exist", err) + ctx.APIError(http.StatusConflict, err) return } if release_service.IsErrProtectedTagName(err) { - ctx.Error(http.StatusUnprocessableEntity, "CreateNewTag", "user not allowed to create protected tag") + ctx.APIError(http.StatusUnprocessableEntity, "user not allowed to create protected tag") return } - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } tag, err := ctx.Repo.GitRepo.GetTag(form.TagName) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusCreated, convert.ToTag(ctx.Repo.Repository, tag)) @@ -267,24 +267,24 @@ func DeleteTag(ctx *context.APIContext) { tag, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, tagName) if err != nil { if repo_model.IsErrReleaseNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() return } - ctx.Error(http.StatusInternalServerError, "GetRelease", err) + ctx.APIErrorInternal(err) return } if !tag.IsTag { - ctx.Error(http.StatusConflict, "IsTag", errors.New("a tag attached to a release cannot be deleted directly")) + ctx.APIError(http.StatusConflict, errors.New("a tag attached to a release cannot be deleted directly")) return } if err = release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, tag, ctx.Doer, true); err != nil { if release_service.IsErrProtectedTagName(err) { - ctx.Error(http.StatusUnprocessableEntity, "delTag", "user not allowed to delete protected tag") + ctx.APIError(http.StatusUnprocessableEntity, "user not allowed to delete protected tag") return } - ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) + ctx.APIErrorInternal(err) return } @@ -316,7 +316,7 @@ func ListTagProtection(ctx *context.APIContext) { repo := ctx.Repo.Repository pts, err := git_model.GetProtectedTags(ctx, repo.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedTags", err) + ctx.APIErrorInternal(err) return } apiPts := make([]*api.TagProtection, len(pts)) @@ -360,12 +360,12 @@ func GetTagProtection(ctx *context.APIContext) { id := ctx.PathParamInt64("id") pt, err := git_model.GetProtectedTagByID(ctx, id) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedTagByID", err) + ctx.APIErrorInternal(err) return } if pt == nil || repo.ID != pt.RepoID { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -413,21 +413,21 @@ func CreateTagProtection(ctx *context.APIContext) { namePattern := strings.TrimSpace(form.NamePattern) if namePattern == "" { - ctx.Error(http.StatusBadRequest, "name_pattern are empty", "name_pattern are empty") + ctx.APIError(http.StatusBadRequest, "name_pattern are empty") return } if len(form.WhitelistUsernames) == 0 && len(form.WhitelistTeams) == 0 { - ctx.Error(http.StatusBadRequest, "both whitelist_usernames and whitelist_teams are empty", "both whitelist_usernames and whitelist_teams are empty") + ctx.APIError(http.StatusBadRequest, "both whitelist_usernames and whitelist_teams are empty") return } pt, err := git_model.GetProtectedTagByNamePattern(ctx, repo.ID, namePattern) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectTagOfRepo", err) + ctx.APIErrorInternal(err) return } else if pt != nil { - ctx.Error(http.StatusForbidden, "Create tag protection", "Tag protection already exist") + ctx.APIError(http.StatusForbidden, "Tag protection already exist") return } @@ -435,10 +435,10 @@ func CreateTagProtection(ctx *context.APIContext) { whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.WhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err) + ctx.APIErrorInternal(err) return } @@ -446,10 +446,10 @@ func CreateTagProtection(ctx *context.APIContext) { whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.WhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err) + ctx.APIErrorInternal(err) return } } @@ -461,18 +461,18 @@ func CreateTagProtection(ctx *context.APIContext) { AllowlistTeamIDs: whitelistTeams, } if err := git_model.InsertProtectedTag(ctx, protectTag); err != nil { - ctx.Error(http.StatusInternalServerError, "InsertProtectedTag", err) + ctx.APIErrorInternal(err) return } pt, err = git_model.GetProtectedTagByID(ctx, protectTag.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedTagByID", err) + ctx.APIErrorInternal(err) return } if pt == nil || pt.RepoID != repo.ID { - ctx.Error(http.StatusInternalServerError, "New tag protection not found", err) + ctx.APIErrorInternal(err) return } @@ -524,12 +524,12 @@ func EditTagProtection(ctx *context.APIContext) { id := ctx.PathParamInt64("id") pt, err := git_model.GetProtectedTagByID(ctx, id) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedTagByID", err) + ctx.APIErrorInternal(err) return } if pt == nil || pt.RepoID != repo.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -543,10 +543,10 @@ func EditTagProtection(ctx *context.APIContext) { whitelistTeams, err = organization.GetTeamIDsByNames(ctx, repo.OwnerID, form.WhitelistTeams, false) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "Team does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetTeamIDsByNames", err) + ctx.APIErrorInternal(err) return } } @@ -557,10 +557,10 @@ func EditTagProtection(ctx *context.APIContext) { whitelistUsers, err = user_model.GetUserIDsByNames(ctx, form.WhitelistUsernames, false) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "User does not exist", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } - ctx.Error(http.StatusInternalServerError, "GetUserIDsByNames", err) + ctx.APIErrorInternal(err) return } pt.AllowlistUserIDs = whitelistUsers @@ -568,18 +568,18 @@ func EditTagProtection(ctx *context.APIContext) { err = git_model.UpdateProtectedTag(ctx, pt) if err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateProtectedTag", err) + ctx.APIErrorInternal(err) return } pt, err = git_model.GetProtectedTagByID(ctx, id) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedTagByID", err) + ctx.APIErrorInternal(err) return } if pt == nil || pt.RepoID != repo.ID { - ctx.Error(http.StatusInternalServerError, "New tag protection not found", "New tag protection not found") + ctx.APIErrorInternal(errors.New("new tag protection not found")) return } @@ -619,18 +619,18 @@ func DeleteTagProtection(ctx *context.APIContext) { id := ctx.PathParamInt64("id") pt, err := git_model.GetProtectedTagByID(ctx, id) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetProtectedTagByID", err) + ctx.APIErrorInternal(err) return } if pt == nil || pt.RepoID != repo.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } err = git_model.DeleteProtectedTag(ctx, pt) if err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteProtectedTag", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go index e5a2d5c320b03..739a9e3892ba0 100644 --- a/routers/api/v1/repo/teams.go +++ b/routers/api/v1/repo/teams.go @@ -38,19 +38,19 @@ func ListTeams(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if !ctx.Repo.Owner.IsOrganization() { - ctx.Error(http.StatusMethodNotAllowed, "noOrg", "repo is not owned by an organization") + ctx.APIError(http.StatusMethodNotAllowed, "repo is not owned by an organization") return } teams, err := organization.GetRepoTeams(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } apiTeams, err := convert.ToTeams(ctx, teams, false) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -89,7 +89,7 @@ func IsTeam(ctx *context.APIContext) { // "$ref": "#/responses/error" if !ctx.Repo.Owner.IsOrganization() { - ctx.Error(http.StatusMethodNotAllowed, "noOrg", "repo is not owned by an organization") + ctx.APIError(http.StatusMethodNotAllowed, "repo is not owned by an organization") return } @@ -101,14 +101,14 @@ func IsTeam(ctx *context.APIContext) { if repo_service.HasRepository(ctx, team, ctx.Repo.Repository.ID) { apiTeam, err := convert.ToTeam(ctx, team) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, apiTeam) return } - ctx.NotFound() + ctx.APIErrorNotFound() } // AddTeam add a team to a repository @@ -185,10 +185,10 @@ func DeleteTeam(ctx *context.APIContext) { func changeRepoTeam(ctx *context.APIContext, add bool) { if !ctx.Repo.Owner.IsOrganization() { - ctx.Error(http.StatusMethodNotAllowed, "noOrg", "repo is not owned by an organization") + ctx.APIError(http.StatusMethodNotAllowed, "repo is not owned by an organization") } if !ctx.Repo.Owner.RepoAdminChangeTeamAccess && !ctx.Repo.IsOwner() { - ctx.Error(http.StatusForbidden, "noAdmin", "user is nor repo admin nor owner") + ctx.APIError(http.StatusForbidden, "user is nor repo admin nor owner") return } @@ -201,19 +201,19 @@ func changeRepoTeam(ctx *context.APIContext, add bool) { var err error if add { if repoHasTeam { - ctx.Error(http.StatusUnprocessableEntity, "alreadyAdded", fmt.Errorf("team '%s' is already added to repo", team.Name)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("team '%s' is already added to repo", team.Name)) return } err = repo_service.TeamAddRepository(ctx, team, ctx.Repo.Repository) } else { if !repoHasTeam { - ctx.Error(http.StatusUnprocessableEntity, "notAdded", fmt.Errorf("team '%s' was not added to repo", team.Name)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("team '%s' was not added to repo", team.Name)) return } err = repo_service.RemoveRepositoryFromTeam(ctx, team, ctx.Repo.Repository.ID) } if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -224,10 +224,10 @@ 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.Error(http.StatusNotFound, "TeamNotExit", err) + ctx.APIError(http.StatusNotFound, err) return nil } - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return nil } return team diff --git a/routers/api/v1/repo/topic.go b/routers/api/v1/repo/topic.go index a1a15e7f46d7d..9c4c22e0398a6 100644 --- a/routers/api/v1/repo/topic.go +++ b/routers/api/v1/repo/topic.go @@ -56,7 +56,7 @@ func ListTopics(ctx *context.APIContext) { topics, total, err := db.FindAndCount[repo_model.Topic](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -124,7 +124,7 @@ func UpdateTopics(ctx *context.APIContext) { err := repo_model.SaveTopics(ctx, ctx.Repo.Repository.ID, validTopics...) if err != nil { log.Error("SaveTopics failed: %v", err) - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -178,7 +178,7 @@ func AddTopic(ctx *context.APIContext) { }) if err != nil { log.Error("CountTopics failed: %v", err) - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if count >= 25 { @@ -191,7 +191,7 @@ func AddTopic(ctx *context.APIContext) { _, err = repo_model.AddTopic(ctx, ctx.Repo.Repository.ID, topicName) if err != nil { log.Error("AddTopic failed: %v", err) - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -242,12 +242,12 @@ func DeleteTopic(ctx *context.APIContext) { topic, err := repo_model.DeleteTopic(ctx, ctx.Repo.Repository.ID, topicName) if err != nil { log.Error("DeleteTopic failed: %v", err) - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if topic == nil { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -290,7 +290,7 @@ func TopicSearch(ctx *context.APIContext) { topics, total, err := db.FindAndCount[repo_model.Topic](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go index bb666f6487ed3..7b890c9e5cdff 100644 --- a/routers/api/v1/repo/transfer.go +++ b/routers/api/v1/repo/transfer.go @@ -61,17 +61,17 @@ func Transfer(ctx *context.APIContext) { newOwner, err := user_model.GetUserByName(ctx, opts.NewOwner) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusNotFound, "", "The new owner does not exist or cannot be found") + ctx.APIError(http.StatusNotFound, "The new owner does not exist or cannot be found") return } - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if newOwner.Type == user_model.UserTypeOrganization { if !ctx.Doer.IsAdmin && newOwner.Visibility == api.VisibleTypePrivate && !organization.OrgFromUser(newOwner).HasMemberWithUserID(ctx, ctx.Doer.ID) { // The user shouldn't know about this organization - ctx.Error(http.StatusNotFound, "", "The new owner does not exist or cannot be found") + ctx.APIError(http.StatusNotFound, "The new owner does not exist or cannot be found") return } } @@ -79,7 +79,7 @@ func Transfer(ctx *context.APIContext) { var teams []*organization.Team if opts.TeamIDs != nil { if !newOwner.IsOrganization() { - ctx.Error(http.StatusUnprocessableEntity, "repoTransfer", "Teams can only be added to organization-owned repositories") + ctx.APIError(http.StatusUnprocessableEntity, "Teams can only be added to organization-owned repositories") return } @@ -87,12 +87,12 @@ func Transfer(ctx *context.APIContext) { for _, tID := range *opts.TeamIDs { team, err := organization.GetTeamByID(ctx, tID) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "team", fmt.Errorf("team %d not found", tID)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("team %d not found", tID)) return } if team.OrgID != org.ID { - ctx.Error(http.StatusForbidden, "team", fmt.Errorf("team %d belongs not to org %d", tID, org.ID)) + ctx.APIError(http.StatusForbidden, fmt.Errorf("team %d belongs not to org %d", tID, org.ID)) return } @@ -109,19 +109,19 @@ func Transfer(ctx *context.APIContext) { if err := repo_service.StartRepositoryTransfer(ctx, ctx.Doer, newOwner, ctx.Repo.Repository, teams); err != nil { if repo_model.IsErrRepoTransferInProgress(err) { - ctx.Error(http.StatusConflict, "StartRepositoryTransfer", err) + ctx.APIError(http.StatusConflict, err) return } if repo_model.IsErrRepoAlreadyExist(err) { - ctx.Error(http.StatusUnprocessableEntity, "StartRepositoryTransfer", err) + ctx.APIError(http.StatusUnprocessableEntity, err) return } if errors.Is(err, user_model.ErrBlockedUser) { - ctx.Error(http.StatusForbidden, "BlockedUser", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) } return } @@ -166,11 +166,11 @@ func AcceptTransfer(ctx *context.APIContext) { if err != nil { switch { case repo_model.IsErrNoPendingTransfer(err): - ctx.Error(http.StatusNotFound, "AcceptTransferOwnership", err) + ctx.APIError(http.StatusNotFound, err) case errors.Is(err, util.ErrPermissionDenied): - ctx.Error(http.StatusForbidden, "AcceptTransferOwnership", err) + ctx.APIError(http.StatusForbidden, err) default: - ctx.Error(http.StatusInternalServerError, "AcceptTransferOwnership", err) + ctx.APIErrorInternal(err) } return } @@ -208,11 +208,11 @@ func RejectTransfer(ctx *context.APIContext) { if err != nil { switch { case repo_model.IsErrNoPendingTransfer(err): - ctx.Error(http.StatusNotFound, "RejectRepositoryTransfer", err) + ctx.APIError(http.StatusNotFound, err) case errors.Is(err, util.ErrPermissionDenied): - ctx.Error(http.StatusForbidden, "RejectRepositoryTransfer", err) + ctx.APIError(http.StatusForbidden, err) default: - ctx.Error(http.StatusInternalServerError, "RejectRepositoryTransfer", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go index 768e5d41c1e37..dfd69600fb091 100644 --- a/routers/api/v1/repo/tree.go +++ b/routers/api/v1/repo/tree.go @@ -58,11 +58,11 @@ func GetTree(ctx *context.APIContext) { sha := ctx.PathParam("sha") if len(sha) == 0 { - ctx.Error(http.StatusBadRequest, "", "sha not provided") + ctx.APIError(http.StatusBadRequest, "sha not provided") return } if tree, err := files_service.GetTreeBySHA(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, sha, ctx.FormInt("page"), ctx.FormInt("per_page"), ctx.FormBool("recursive")); err != nil { - ctx.Error(http.StatusBadRequest, "", err.Error()) + ctx.APIError(http.StatusBadRequest, err.Error()) } else { ctx.SetTotalCountHeader(int64(tree.TotalCount)) ctx.JSON(http.StatusOK, tree) diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index 352d8f48fc082..8d73383f76573 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.Error(http.StatusBadRequest, "emptyTitle", nil) + ctx.APIError(http.StatusBadRequest, nil) return } @@ -71,18 +71,18 @@ func NewWikiPage(ctx *context.APIContext) { content, err := base64.StdEncoding.DecodeString(form.ContentBase64) if err != nil { - ctx.Error(http.StatusBadRequest, "invalid base64 encoding of content", err) + ctx.APIError(http.StatusBadRequest, err) return } form.ContentBase64 = string(content) if err := wiki_service.AddWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName, form.ContentBase64, form.Message); err != nil { if repo_model.IsErrWikiReservedName(err) { - ctx.Error(http.StatusBadRequest, "IsErrWikiReservedName", err) + ctx.APIError(http.StatusBadRequest, err) } else if repo_model.IsErrWikiAlreadyExist(err) { - ctx.Error(http.StatusBadRequest, "IsErrWikiAlreadyExists", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "AddWikiPage", err) + ctx.APIErrorInternal(err) } return } @@ -149,13 +149,13 @@ func EditWikiPage(ctx *context.APIContext) { content, err := base64.StdEncoding.DecodeString(form.ContentBase64) if err != nil { - ctx.Error(http.StatusBadRequest, "invalid base64 encoding of content", err) + ctx.APIError(http.StatusBadRequest, err) return } form.ContentBase64 = string(content) if err := wiki_service.EditWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, oldWikiName, newWikiName, form.ContentBase64, form.Message); err != nil { - ctx.Error(http.StatusInternalServerError, "EditWikiPage", err) + ctx.APIErrorInternal(err) return } @@ -198,7 +198,7 @@ func getWikiPage(ctx *context.APIContext, wikiName wiki_service.WebPath) *api.Wi // Get last change information. lastCommit, err := wikiRepo.GetCommitByPath(pageFilename) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommitByPath", err) + ctx.APIErrorInternal(err) return nil } @@ -246,10 +246,10 @@ func DeleteWikiPage(ctx *context.APIContext) { if err := wiki_service.DeleteWikiPage(ctx, ctx.Doer, ctx.Repo.Repository, wikiName); err != nil { if err.Error() == "file does not exist" { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) return } - ctx.Error(http.StatusInternalServerError, "DeleteWikiPage", err) + ctx.APIErrorInternal(err) return } @@ -312,7 +312,7 @@ func ListWikiPages(ctx *context.APIContext) { entries, err := commit.ListEntries() if err != nil { - ctx.ServerError("ListEntries", err) + ctx.APIErrorInternal(err) return } pages := make([]*api.WikiPageMetaData, 0, len(entries)) @@ -322,7 +322,7 @@ func ListWikiPages(ctx *context.APIContext) { } c, err := wikiRepo.GetCommitByPath(entry.Name()) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommit", err) + ctx.APIErrorInternal(err) return } wikiName, err := wiki_service.GitPathToWebPath(entry.Name()) @@ -330,7 +330,7 @@ func ListWikiPages(ctx *context.APIContext) { if repo_model.IsErrWikiInvalidFileName(err) { continue } - ctx.Error(http.StatusInternalServerError, "WikiFilenameToName", err) + ctx.APIErrorInternal(err) return } pages = append(pages, wiki_service.ToWikiPageMetaData(wikiName, c, ctx.Repo.Repository)) @@ -447,7 +447,7 @@ func ListPageRevisions(ctx *context.APIContext) { Page: page, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) + ctx.APIErrorInternal(err) return } @@ -479,9 +479,9 @@ func findWikiRepoCommit(ctx *context.APIContext) (*git.Repository, *git.Commit) wikiRepo, err := gitrepo.OpenWikiRepository(ctx, ctx.Repo.Repository) if err != nil { if git.IsErrNotExist(err) || err.Error() == "no such file or directory" { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "OpenRepository", err) + ctx.APIErrorInternal(err) } return nil, nil } @@ -489,9 +489,9 @@ func findWikiRepoCommit(ctx *context.APIContext) (*git.Repository, *git.Commit) commit, err := wikiRepo.GetBranchCommit("master") if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound(err) + ctx.APIErrorNotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetBranchCommit", err) + ctx.APIErrorInternal(err) } return wikiRepo, nil } @@ -507,7 +507,7 @@ func wikiContentsByEntry(ctx *context.APIContext, entry *git.TreeEntry) string { } content, err := blob.GetBlobContentBase64() if err != nil { - ctx.Error(http.StatusInternalServerError, "GetBlobContentBase64", err) + ctx.APIErrorInternal(err) return "" } return content @@ -521,10 +521,10 @@ func wikiContentsByName(ctx *context.APIContext, commit *git.Commit, wikiName wi if err != nil { if git.IsErrNotExist(err) { if !isSidebarOrFooter { - ctx.NotFound() + ctx.APIErrorNotFound() } } else { - ctx.ServerError("findEntryForFile", err) + ctx.APIErrorInternal(err) } return "", "" } diff --git a/routers/api/v1/shared/block.go b/routers/api/v1/shared/block.go index 490a48f81c858..b22f8a74fd465 100644 --- a/routers/api/v1/shared/block.go +++ b/routers/api/v1/shared/block.go @@ -21,12 +21,12 @@ func ListBlocks(ctx *context.APIContext, blocker *user_model.User) { BlockerID: blocker.ID, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindBlockings", err) + ctx.APIErrorInternal(err) return } if err := user_model.BlockingList(blocks).LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) + ctx.APIErrorInternal(err) return } @@ -42,14 +42,14 @@ func ListBlocks(ctx *context.APIContext, blocker *user_model.User) { func CheckUserBlock(ctx *context.APIContext, blocker *user_model.User) { blockee, err := user_model.GetUserByName(ctx, ctx.PathParam("username")) if err != nil { - ctx.NotFound("GetUserByName", err) + ctx.APIErrorNotFound("GetUserByName", err) return } status := http.StatusNotFound blocking, err := user_model.GetBlocking(ctx, blocker.ID, blockee.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetBlocking", err) + ctx.APIErrorInternal(err) return } if blocking != nil { @@ -62,15 +62,15 @@ func CheckUserBlock(ctx *context.APIContext, blocker *user_model.User) { func BlockUser(ctx *context.APIContext, blocker *user_model.User) { blockee, err := user_model.GetUserByName(ctx, ctx.PathParam("username")) if err != nil { - ctx.NotFound("GetUserByName", err) + ctx.APIErrorNotFound("GetUserByName", err) return } 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.Error(http.StatusBadRequest, "BlockUser", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "BlockUser", err) + ctx.APIErrorInternal(err) } return } @@ -81,15 +81,15 @@ func BlockUser(ctx *context.APIContext, blocker *user_model.User) { func UnblockUser(ctx *context.APIContext, doer, blocker *user_model.User) { blockee, err := user_model.GetUserByName(ctx, ctx.PathParam("username")) if err != nil { - ctx.NotFound("GetUserByName", err) + ctx.APIErrorNotFound("GetUserByName", err) return } 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.Error(http.StatusBadRequest, "UnblockUser", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "UnblockUser", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/shared/runners.go b/routers/api/v1/shared/runners.go index f088e9a2d411f..f31d9e5d0bdf0 100644 --- a/routers/api/v1/shared/runners.go +++ b/routers/api/v1/shared/runners.go @@ -24,7 +24,7 @@ func GetRegistrationToken(ctx *context.APIContext, ownerID, repoID int64) { token, err = actions_model.NewRunnerToken(ctx, ownerID, repoID) } if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/user/action.go b/routers/api/v1/user/action.go index baa4b3b81ec74..1c8e3b6e71fa1 100644 --- a/routers/api/v1/user/action.go +++ b/routers/api/v1/user/action.go @@ -52,11 +52,11 @@ func CreateOrUpdateSecret(ctx *context.APIContext) { _, created, err := secret_service.CreateOrUpdateSecret(ctx, ctx.Doer.ID, 0, ctx.PathParam("secretname"), opt.Data) if err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "CreateOrUpdateSecret", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateOrUpdateSecret", err) + ctx.APIErrorInternal(err) } return } @@ -94,11 +94,11 @@ 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.Error(http.StatusBadRequest, "DeleteSecret", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "DeleteSecret", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "DeleteSecret", err) + ctx.APIErrorInternal(err) } return } @@ -145,19 +145,19 @@ func CreateVariable(ctx *context.APIContext) { Name: variableName, }) if err != nil && !errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusInternalServerError, "GetVariable", err) + ctx.APIErrorInternal(err) return } if v != nil && v.ID > 0 { - ctx.Error(http.StatusConflict, "VariableNameAlreadyExists", util.NewAlreadyExistErrorf("variable name %s already exists", variableName)) + ctx.APIError(http.StatusConflict, util.NewAlreadyExistErrorf("variable name %s already exists", variableName)) return } if _, err := actions_service.CreateVariable(ctx, ownerID, 0, variableName, opt.Value); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusBadRequest, "CreateVariable", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "CreateVariable", err) + ctx.APIErrorInternal(err) } return } @@ -202,9 +202,9 @@ func UpdateVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "GetVariable", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetVariable", err) + ctx.APIErrorInternal(err) } return } @@ -218,9 +218,9 @@ func UpdateVariable(ctx *context.APIContext) { if _, err := actions_service.UpdateVariableNameData(ctx, v); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusBadRequest, "UpdateVariable", err) + ctx.APIError(http.StatusBadRequest, err) } else { - ctx.Error(http.StatusInternalServerError, "UpdateVariable", err) + ctx.APIErrorInternal(err) } return } @@ -253,11 +253,11 @@ 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.Error(http.StatusBadRequest, "DeleteVariableByName", err) + ctx.APIError(http.StatusBadRequest, err) } else if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "DeleteVariableByName", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "DeleteVariableByName", err) + ctx.APIErrorInternal(err) } return } @@ -292,9 +292,9 @@ func GetVariable(ctx *context.APIContext) { }) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, "GetVariable", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetVariable", err) + ctx.APIErrorInternal(err) } return } @@ -338,7 +338,7 @@ func ListVariables(ctx *context.APIContext) { ListOptions: utils.GetListOptions(ctx), }) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindVariables", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go index bfbc2ba6220ac..4ca06ca923886 100644 --- a/routers/api/v1/user/app.go +++ b/routers/api/v1/user/app.go @@ -51,7 +51,7 @@ func ListAccessTokens(ctx *context.APIContext) { tokens, count, err := db.FindAndCount[auth_model.AccessToken](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -105,27 +105,27 @@ func CreateAccessToken(ctx *context.APIContext) { exist, err := auth_model.AccessTokenByNameExists(ctx, t) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } if exist { - ctx.Error(http.StatusBadRequest, "AccessTokenByNameExists", errors.New("access token name has been used already")) + ctx.APIError(http.StatusBadRequest, errors.New("access token name has been used already")) return } scope, err := auth_model.AccessTokenScope(strings.Join(form.Scopes, ",")).Normalize() if err != nil { - ctx.Error(http.StatusBadRequest, "AccessTokenScope.Normalize", fmt.Errorf("invalid access token scope provided: %w", err)) + ctx.APIError(http.StatusBadRequest, fmt.Errorf("invalid access token scope provided: %w", err)) return } if scope == "" { - ctx.Error(http.StatusBadRequest, "AccessTokenScope", "access token must have a scope") + ctx.APIError(http.StatusBadRequest, "access token must have a scope") return } t.Scope = scope if err := auth_model.NewAccessToken(ctx, t); err != nil { - ctx.Error(http.StatusInternalServerError, "NewAccessToken", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusCreated, &api.AccessToken{ @@ -174,31 +174,31 @@ func DeleteAccessToken(ctx *context.APIContext) { UserID: ctx.ContextUser.ID, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "ListAccessTokens", err) + ctx.APIErrorInternal(err) return } switch len(tokens) { case 0: - ctx.NotFound() + ctx.APIErrorNotFound() return case 1: tokenID = tokens[0].ID default: - ctx.Error(http.StatusUnprocessableEntity, "DeleteAccessTokenByID", fmt.Errorf("multiple matches for token name '%s'", token)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("multiple matches for token name '%s'", token)) return } } if tokenID == 0 { - ctx.Error(http.StatusInternalServerError, "Invalid TokenID", nil) + ctx.APIErrorInternal(nil) return } if err := auth_model.DeleteAccessTokenByID(ctx, tokenID, ctx.ContextUser.ID); err != nil { if auth_model.IsErrAccessTokenNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "DeleteAccessTokenByID", err) + ctx.APIErrorInternal(err) } return } @@ -235,12 +235,12 @@ func CreateOauth2Application(ctx *context.APIContext) { SkipSecondaryAuthorization: data.SkipSecondaryAuthorization, }) if err != nil { - ctx.Error(http.StatusBadRequest, "", "error creating oauth2 application") + ctx.APIError(http.StatusBadRequest, "error creating oauth2 application") return } secret, err := app.GenerateClientSecret(ctx) if err != nil { - ctx.Error(http.StatusBadRequest, "", "error creating application secret") + ctx.APIError(http.StatusBadRequest, "error creating application secret") return } app.ClientSecret = secret @@ -273,7 +273,7 @@ func ListOauth2Applications(ctx *context.APIContext) { OwnerID: ctx.Doer.ID, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "ListOAuth2Applications", err) + ctx.APIErrorInternal(err) return } @@ -309,9 +309,9 @@ func DeleteOauth2Application(ctx *context.APIContext) { appID := ctx.PathParamInt64("id") if err := auth_model.DeleteOAuth2Application(ctx, appID, ctx.Doer.ID); err != nil { if auth_model.IsErrOAuthApplicationNotFound(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "DeleteOauth2ApplicationByID", err) + ctx.APIErrorInternal(err) } return } @@ -342,14 +342,14 @@ func GetOauth2Application(ctx *context.APIContext) { app, err := auth_model.GetOAuth2ApplicationByID(ctx, appID) if err != nil { if auth_model.IsErrOauthClientIDInvalid(err) || auth_model.IsErrOAuthApplicationNotFound(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetOauth2ApplicationByID", err) + ctx.APIErrorInternal(err) } return } if app.UID != ctx.Doer.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -396,15 +396,15 @@ func UpdateOauth2Application(ctx *context.APIContext) { }) if err != nil { if auth_model.IsErrOauthClientIDInvalid(err) || auth_model.IsErrOAuthApplicationNotFound(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "UpdateOauth2ApplicationByID", err) + ctx.APIErrorInternal(err) } return } app.ClientSecret, err = app.GenerateClientSecret(ctx) if err != nil { - ctx.Error(http.StatusBadRequest, "", "error updating application secret") + ctx.APIError(http.StatusBadRequest, "error updating application secret") return } diff --git a/routers/api/v1/user/avatar.go b/routers/api/v1/user/avatar.go index 30ccb63587b9d..9c7bd57bc06ca 100644 --- a/routers/api/v1/user/avatar.go +++ b/routers/api/v1/user/avatar.go @@ -32,13 +32,13 @@ func UpdateAvatar(ctx *context.APIContext) { content, err := base64.StdEncoding.DecodeString(form.Image) if err != nil { - ctx.Error(http.StatusBadRequest, "DecodeImage", err) + ctx.APIError(http.StatusBadRequest, err) return } err = user_service.UploadAvatar(ctx, ctx.Doer, content) if err != nil { - ctx.Error(http.StatusInternalServerError, "UploadAvatar", err) + ctx.APIErrorInternal(err) return } @@ -57,7 +57,7 @@ func DeleteAvatar(ctx *context.APIContext) { // "$ref": "#/responses/empty" err := user_service.DeleteAvatar(ctx, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "DeleteAvatar", err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go index 33aa851a80716..055e5ea419742 100644 --- a/routers/api/v1/user/email.go +++ b/routers/api/v1/user/email.go @@ -29,7 +29,7 @@ func ListEmails(ctx *context.APIContext) { emails, err := user_model.GetEmailAddresses(ctx, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetEmailAddresses", err) + ctx.APIErrorInternal(err) return } apiEmails := make([]*api.Email, len(emails)) @@ -59,13 +59,13 @@ func AddEmail(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.CreateEmailOption) if len(form.Emails) == 0 { - ctx.Error(http.StatusUnprocessableEntity, "", "Email list empty") + ctx.APIError(http.StatusUnprocessableEntity, "Email list empty") return } if err := user_service.AddEmailAddresses(ctx, ctx.Doer, form.Emails); err != nil { if user_model.IsErrEmailAlreadyUsed(err) { - ctx.Error(http.StatusUnprocessableEntity, "", "Email address has been used: "+err.(user_model.ErrEmailAlreadyUsed).Email) + ctx.APIError(http.StatusUnprocessableEntity, "Email address has been used: "+err.(user_model.ErrEmailAlreadyUsed).Email) } else if user_model.IsErrEmailCharIsNotSupported(err) || user_model.IsErrEmailInvalid(err) { email := "" if typedError, ok := err.(user_model.ErrEmailInvalid); ok { @@ -76,16 +76,16 @@ func AddEmail(ctx *context.APIContext) { } errMsg := fmt.Sprintf("Email address %q invalid", email) - ctx.Error(http.StatusUnprocessableEntity, "", errMsg) + ctx.APIError(http.StatusUnprocessableEntity, errMsg) } else { - ctx.Error(http.StatusInternalServerError, "AddEmailAddresses", err) + ctx.APIErrorInternal(err) } return } emails, err := user_model.GetEmailAddresses(ctx, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetEmailAddresses", err) + ctx.APIErrorInternal(err) return } @@ -122,9 +122,9 @@ func DeleteEmail(ctx *context.APIContext) { if err := user_service.DeleteEmailAddresses(ctx, ctx.Doer, form.Emails); err != nil { if user_model.IsErrEmailAddressNotExist(err) { - ctx.Error(http.StatusNotFound, "DeleteEmailAddresses", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "DeleteEmailAddresses", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go index 8f46808f9ec8c..0d0c0be7e012c 100644 --- a/routers/api/v1/user/follower.go +++ b/routers/api/v1/user/follower.go @@ -26,7 +26,7 @@ func responseAPIUsers(ctx *context.APIContext, users []*user_model.User) { func listUserFollowers(ctx *context.APIContext, u *user_model.User) { users, count, err := user_model.GetUserFollowers(ctx, u, ctx.Doer, utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserFollowers", err) + ctx.APIErrorInternal(err) return } @@ -90,7 +90,7 @@ func ListFollowers(ctx *context.APIContext) { func listUserFollowing(ctx *context.APIContext, u *user_model.User) { users, count, err := user_model.GetUserFollowing(ctx, u, ctx.Doer, utils.GetListOptions(ctx)) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserFollowing", err) + ctx.APIErrorInternal(err) return } @@ -155,7 +155,7 @@ func checkUserFollowing(ctx *context.APIContext, u *user_model.User, followID in if user_model.IsFollowing(ctx, u.ID, followID) { ctx.Status(http.StatusNoContent) } else { - ctx.NotFound() + ctx.APIErrorNotFound() } } @@ -229,9 +229,9 @@ 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.Error(http.StatusForbidden, "FollowUser", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "FollowUser", err) + ctx.APIErrorInternal(err) } return } @@ -256,7 +256,7 @@ func Unfollow(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if err := user_model.UnfollowUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID); err != nil { - ctx.Error(http.StatusInternalServerError, "UnfollowUser", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go index ef667a188329c..504e74ae100cc 100644 --- a/routers/api/v1/user/gpg_key.go +++ b/routers/api/v1/user/gpg_key.go @@ -25,12 +25,12 @@ func listGPGKeys(ctx *context.APIContext, uid int64, listOptions db.ListOptions) OwnerID: uid, }) if err != nil { - ctx.Error(http.StatusInternalServerError, "ListGPGKeys", err) + ctx.APIErrorInternal(err) return } if err := asymkey_model.GPGKeyList(keys).LoadSubKeys(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "ListGPGKeys", err) + ctx.APIErrorInternal(err) return } @@ -119,14 +119,14 @@ func GetGPGKey(ctx *context.APIContext) { key, err := asymkey_model.GetGPGKeyForUserByID(ctx, ctx.Doer.ID, ctx.PathParamInt64("id")) if err != nil { if asymkey_model.IsErrGPGKeyNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetGPGKeyByID", err) + ctx.APIErrorInternal(err) } return } if err := key.LoadSubKeys(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadSubKeys", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, convert.ToGPGKey(key)) @@ -135,7 +135,7 @@ func GetGPGKey(ctx *context.APIContext) { // CreateUserGPGKey creates new GPG key to given user by ID. func CreateUserGPGKey(ctx *context.APIContext, form api.CreateGPGKeyOption, uid int64) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageGPGKeys) { - ctx.NotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) + ctx.APIErrorNotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) return } @@ -194,7 +194,7 @@ func VerifyUserGPGKey(ctx *context.APIContext) { form.KeyID = strings.TrimLeft(form.KeyID, "0") if form.KeyID == "" { - ctx.NotFound() + ctx.APIErrorNotFound() return } @@ -205,10 +205,10 @@ func VerifyUserGPGKey(ctx *context.APIContext) { if err != nil { if asymkey_model.IsErrGPGInvalidTokenSignature(err) { - ctx.Error(http.StatusUnprocessableEntity, "GPGInvalidSignature", fmt.Sprintf("The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: %s", token)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: %s", token)) return } - ctx.Error(http.StatusInternalServerError, "VerifyUserGPGKey", err) + ctx.APIErrorInternal(err) } keys, err := db.Find[asymkey_model.GPGKey](ctx, asymkey_model.FindGPGKeyOptions{ @@ -217,9 +217,9 @@ func VerifyUserGPGKey(ctx *context.APIContext) { }) if err != nil { if asymkey_model.IsErrGPGKeyNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetGPGKeysByKeyID", err) + ctx.APIErrorInternal(err) } return } @@ -276,15 +276,15 @@ func DeleteGPGKey(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageGPGKeys) { - ctx.NotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) + ctx.APIErrorNotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) return } if err := asymkey_model.DeleteGPGKey(ctx, ctx.Doer, ctx.PathParamInt64("id")); err != nil { if asymkey_model.IsErrGPGKeyAccessDenied(err) { - ctx.Error(http.StatusForbidden, "", "You do not have access to this key") + ctx.APIError(http.StatusForbidden, "You do not have access to this key") } else { - ctx.Error(http.StatusInternalServerError, "DeleteGPGKey", err) + ctx.APIErrorInternal(err) } return } @@ -296,16 +296,16 @@ func DeleteGPGKey(ctx *context.APIContext) { func HandleAddGPGKeyError(ctx *context.APIContext, err error, token string) { switch { case asymkey_model.IsErrGPGKeyAccessDenied(err): - ctx.Error(http.StatusUnprocessableEntity, "GPGKeyAccessDenied", "You do not have access to this GPG key") + ctx.APIError(http.StatusUnprocessableEntity, "You do not have access to this GPG key") case asymkey_model.IsErrGPGKeyIDAlreadyUsed(err): - ctx.Error(http.StatusUnprocessableEntity, "GPGKeyIDAlreadyUsed", "A key with the same id already exists") + ctx.APIError(http.StatusUnprocessableEntity, "A key with the same id already exists") case asymkey_model.IsErrGPGKeyParsing(err): - ctx.Error(http.StatusUnprocessableEntity, "GPGKeyParsing", err) + ctx.APIError(http.StatusUnprocessableEntity, err) case asymkey_model.IsErrGPGNoEmailFound(err): - ctx.Error(http.StatusNotFound, "GPGNoEmailFound", fmt.Sprintf("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: %s", token)) + ctx.APIError(http.StatusNotFound, fmt.Sprintf("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: %s", token)) case asymkey_model.IsErrGPGInvalidTokenSignature(err): - ctx.Error(http.StatusUnprocessableEntity, "GPGInvalidSignature", fmt.Sprintf("The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: %s", token)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: %s", token)) default: - ctx.Error(http.StatusInternalServerError, "AddGPGKey", err) + ctx.APIErrorInternal(err) } } diff --git a/routers/api/v1/user/helper.go b/routers/api/v1/user/helper.go index 9a6f305700d46..f49bbbd6db240 100644 --- a/routers/api/v1/user/helper.go +++ b/routers/api/v1/user/helper.go @@ -4,8 +4,6 @@ package user import ( - "net/http" - user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/services/context" ) @@ -20,10 +18,10 @@ func GetUserByPathParam(ctx *context.APIContext, name string) *user_model.User { if redirectUserID, err2 := user_model.LookupUserRedirect(ctx, username); err2 == nil { context.RedirectToUser(ctx.Base, username, redirectUserID) } else { - ctx.NotFound("GetUserByName", err) + ctx.APIErrorNotFound("GetUserByName", err) } } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err) + ctx.APIErrorInternal(err) } return nil } diff --git a/routers/api/v1/user/hook.go b/routers/api/v1/user/hook.go index b4605c8a29208..73c98ce746b7b 100644 --- a/routers/api/v1/user/hook.go +++ b/routers/api/v1/user/hook.go @@ -63,13 +63,13 @@ func GetHook(ctx *context.APIContext) { } if !ctx.Doer.IsAdmin && hook.OwnerID != ctx.Doer.ID { - ctx.NotFound() + ctx.APIErrorNotFound() return } apiHook, err := webhook_service.ToHook(ctx.Doer.HomeLink(), hook) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, apiHook) diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go index 5a9125b4f30a5..6295f4753b81b 100644 --- a/routers/api/v1/user/key.go +++ b/routers/api/v1/user/key.go @@ -81,7 +81,7 @@ func listPublicKeys(ctx *context.APIContext, user *user_model.User) { } if err != nil { - ctx.Error(http.StatusInternalServerError, "ListPublicKeys", err) + ctx.APIErrorInternal(err) return } @@ -182,9 +182,9 @@ func GetPublicKey(ctx *context.APIContext) { key, err := asymkey_model.GetPublicKeyByID(ctx, ctx.PathParamInt64("id")) if err != nil { if asymkey_model.IsErrKeyNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetPublicKeyByID", err) + ctx.APIErrorInternal(err) } return } @@ -200,7 +200,7 @@ func GetPublicKey(ctx *context.APIContext) { // CreateUserPublicKey creates new public key to given user by ID. func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid int64) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) { - ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + ctx.APIErrorNotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) return } @@ -270,7 +270,7 @@ func DeletePublicKey(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) { - ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + ctx.APIErrorNotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) return } @@ -278,23 +278,23 @@ func DeletePublicKey(ctx *context.APIContext) { externallyManaged, err := asymkey_model.PublicKeyIsExternallyManaged(ctx, id) if err != nil { if asymkey_model.IsErrKeyNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "PublicKeyIsExternallyManaged", err) + ctx.APIErrorInternal(err) } return } if externallyManaged { - ctx.Error(http.StatusForbidden, "", "SSH Key is externally managed for this user") + ctx.APIError(http.StatusForbidden, "SSH Key is externally managed for this user") return } if err := asymkey_service.DeletePublicKey(ctx, ctx.Doer, id); err != nil { if asymkey_model.IsErrKeyAccessDenied(err) { - ctx.Error(http.StatusForbidden, "", "You do not have access to this key") + ctx.APIError(http.StatusForbidden, "You do not have access to this key") } else { - ctx.Error(http.StatusInternalServerError, "DeletePublicKey", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go index 611134142311b..6aabc4fb90089 100644 --- a/routers/api/v1/user/repo.go +++ b/routers/api/v1/user/repo.go @@ -26,12 +26,12 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) { OrderBy: "id ASC", }) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepositories", err) + ctx.APIErrorInternal(err) return } if err := repos.LoadAttributes(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "RepositoryList.LoadAttributes", err) + ctx.APIErrorInternal(err) return } @@ -39,7 +39,7 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) { for i := range repos { permission, err := access_model.GetUserRepoPermission(ctx, repos[i], ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) return } if ctx.IsSigned && ctx.Doer.IsAdmin || permission.HasAnyUnitAccess() { @@ -113,19 +113,19 @@ func ListMyRepos(ctx *context.APIContext) { repos, count, err := repo_model.SearchRepository(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchRepository", err) + ctx.APIErrorInternal(err) return } results := make([]*api.Repository, len(repos)) for i, repo := range repos { if err = repo.LoadOwner(ctx); err != nil { - ctx.Error(http.StatusInternalServerError, "LoadOwner", err) + ctx.APIErrorInternal(err) return } permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err) + ctx.APIErrorInternal(err) } results[i] = convert.ToRepo(ctx, repo, permission) } diff --git a/routers/api/v1/user/settings.go b/routers/api/v1/user/settings.go index d0a8daaa85ba5..d67c54b339782 100644 --- a/routers/api/v1/user/settings.go +++ b/routers/api/v1/user/settings.go @@ -57,7 +57,7 @@ func UpdateUserSettings(ctx *context.APIContext) { KeepActivityPrivate: optional.FromPtr(form.HideActivity), } if err := user_service.UpdateUser(ctx, ctx.Doer, opts); err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go index 70e54bc1ae4d9..4b0cb45d67ec6 100644 --- a/routers/api/v1/user/star.go +++ b/routers/api/v1/user/star.go @@ -72,7 +72,7 @@ func GetStarredRepos(ctx *context.APIContext) { private := ctx.ContextUser.ID == ctx.Doer.ID repos, err := getStarredRepos(ctx, ctx.ContextUser, private) if err != nil { - ctx.Error(http.StatusInternalServerError, "getStarredRepos", err) + ctx.APIErrorInternal(err) return } @@ -104,7 +104,7 @@ func GetMyStarredRepos(ctx *context.APIContext) { repos, err := getStarredRepos(ctx, ctx.Doer, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "getStarredRepos", err) + ctx.APIErrorInternal(err) } ctx.SetTotalCountHeader(int64(ctx.Doer.NumStars)) @@ -138,7 +138,7 @@ func IsStarring(ctx *context.APIContext) { if repo_model.IsStaring(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID) { ctx.Status(http.StatusNoContent) } else { - ctx.NotFound() + ctx.APIErrorNotFound() } } @@ -169,9 +169,9 @@ 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.Error(http.StatusForbidden, "BlockedUser", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "StarRepo", err) + ctx.APIErrorInternal(err) } return } @@ -204,7 +204,7 @@ func Unstar(ctx *context.APIContext) { err := repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, false) if err != nil { - ctx.Error(http.StatusInternalServerError, "StarRepo", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go index 43dabe1b60c1e..757a548518c0c 100644 --- a/routers/api/v1/user/user.go +++ b/routers/api/v1/user/user.go @@ -121,7 +121,7 @@ func GetInfo(ctx *context.APIContext) { if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) { // fake ErrUserNotExist error message to not leak information about existence - ctx.NotFound("GetUserByName", user_model.ErrUserNotExist{Name: ctx.PathParam("username")}) + ctx.APIErrorNotFound("GetUserByName", user_model.ErrUserNotExist{Name: ctx.PathParam("username")}) return } ctx.JSON(http.StatusOK, convert.ToUser(ctx, ctx.ContextUser, ctx.Doer)) @@ -162,7 +162,7 @@ func GetUserHeatmapData(ctx *context.APIContext) { heatmap, err := activities_model.GetUserHeatmapDataByUser(ctx, ctx.ContextUser, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserHeatmapDataByUser", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, heatmap) @@ -217,7 +217,7 @@ func ListUserActivityFeeds(ctx *context.APIContext) { feeds, count, err := feed_service.GetFeeds(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetFeeds", err) + ctx.APIErrorInternal(err) return } ctx.SetTotalCountHeader(count) diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go index 2cc23ae4763c9..76d7c817937ef 100644 --- a/routers/api/v1/user/watch.go +++ b/routers/api/v1/user/watch.go @@ -68,7 +68,7 @@ func GetWatchedRepos(ctx *context.APIContext) { private := ctx.ContextUser.ID == ctx.Doer.ID repos, total, err := getWatchedRepos(ctx, ctx.ContextUser, private) if err != nil { - ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err) + ctx.APIErrorInternal(err) } ctx.SetTotalCountHeader(total) @@ -97,7 +97,7 @@ func GetMyWatchedRepos(ctx *context.APIContext) { repos, total, err := getWatchedRepos(ctx, ctx.Doer, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err) + ctx.APIErrorInternal(err) } ctx.SetTotalCountHeader(total) @@ -137,7 +137,7 @@ func IsWatching(ctx *context.APIContext) { RepositoryURL: ctx.Repo.Repository.APIURL(), }) } else { - ctx.NotFound() + ctx.APIErrorNotFound() } } @@ -168,9 +168,9 @@ 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.Error(http.StatusForbidden, "BlockedUser", err) + ctx.APIError(http.StatusForbidden, err) } else { - ctx.Error(http.StatusInternalServerError, "WatchRepo", err) + ctx.APIErrorInternal(err) } return } @@ -208,7 +208,7 @@ func Unwatch(ctx *context.APIContext) { err := repo_model.WatchRepo(ctx, ctx.Doer, ctx.Repo.Repository, false) if err != nil { - ctx.Error(http.StatusInternalServerError, "UnwatchRepo", err) + ctx.APIErrorInternal(err) return } ctx.Status(http.StatusNoContent) diff --git a/routers/api/v1/utils/git.go b/routers/api/v1/utils/git.go index 4e25137817e1f..af672ba14766e 100644 --- a/routers/api/v1/utils/git.go +++ b/routers/api/v1/utils/git.go @@ -17,7 +17,7 @@ import ( // ResolveRefOrSha resolve ref to sha if exist func ResolveRefOrSha(ctx *context.APIContext, ref string) string { if len(ref) == 0 { - ctx.Error(http.StatusBadRequest, "ref not given", nil) + ctx.APIError(http.StatusBadRequest, nil) return "" } @@ -26,7 +26,7 @@ func ResolveRefOrSha(ctx *context.APIContext, ref string) string { for _, refType := range []string{"heads", "tags"} { refSHA, lastMethodName, err := searchRefCommitByType(ctx, refType, ref) if err != nil { - ctx.Error(http.StatusInternalServerError, lastMethodName, err) + ctx.APIErrorInternal(fmt.Errorf("%s: %w", lastMethodName, err)) return "" } if refSHA != "" { diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go index 2ad9eeb0ec3d9..9c49819970f33 100644 --- a/routers/api/v1/utils/hook.go +++ b/routers/api/v1/utils/hook.go @@ -30,7 +30,7 @@ func ListOwnerHooks(ctx *context.APIContext, owner *user_model.User) { hooks, count, err := db.FindAndCount[webhook.Webhook](ctx, opts) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } @@ -38,7 +38,7 @@ func ListOwnerHooks(ctx *context.APIContext, owner *user_model.User) { for i, hook := range hooks { apiHooks[i], err = webhook_service.ToHook(owner.HomeLink(), hook) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } } @@ -52,9 +52,9 @@ func GetOwnerHook(ctx *context.APIContext, ownerID, hookID int64) (*webhook.Webh w, err := webhook.GetWebhookByOwnerID(ctx, ownerID, hookID) if err != nil { if webhook.IsErrWebhookNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetWebhookByOwnerID", err) + ctx.APIErrorInternal(err) } return nil, err } @@ -67,9 +67,9 @@ func GetRepoHook(ctx *context.APIContext, repoID, hookID int64) (*webhook.Webhoo w, err := webhook.GetWebhookByRepoID(ctx, repoID, hookID) if err != nil { if webhook.IsErrWebhookNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "GetWebhookByID", err) + ctx.APIErrorInternal(err) } return nil, err } @@ -80,17 +80,17 @@ func GetRepoHook(ctx *context.APIContext, repoID, hookID int64) (*webhook.Webhoo // write the appropriate error to `ctx`. Return whether the form is valid func checkCreateHookOption(ctx *context.APIContext, form *api.CreateHookOption) bool { if !webhook_service.IsValidHookTaskType(form.Type) { - ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Invalid hook type: %s", form.Type)) + ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid hook type: %s", form.Type)) return false } for _, name := range []string{"url", "content_type"} { if _, ok := form.Config[name]; !ok { - ctx.Error(http.StatusUnprocessableEntity, "", "Missing config option: "+name) + ctx.APIError(http.StatusUnprocessableEntity, "Missing config option: "+name) return false } } if !webhook.IsValidHookContentType(form.Config["content_type"]) { - ctx.Error(http.StatusUnprocessableEntity, "", "Invalid content type") + ctx.APIError(http.StatusUnprocessableEntity, "Invalid content type") return false } return true @@ -102,7 +102,7 @@ func AddSystemHook(ctx *context.APIContext, form *api.CreateHookOption) { if ok { h, err := webhook_service.ToHook(setting.AppSubURL+"/-/admin", hook) if err != nil { - ctx.Error(http.StatusInternalServerError, "convert.ToHook", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusCreated, h) @@ -141,7 +141,7 @@ func AddRepoHook(ctx *context.APIContext, form *api.CreateHookOption) { func toAPIHook(ctx *context.APIContext, repoLink string, hook *webhook.Webhook) (*api.Hook, bool) { apiHook, err := webhook_service.ToHook(repoLink, hook) if err != nil { - ctx.Error(http.StatusInternalServerError, "ToHook", err) + ctx.APIErrorInternal(err) return nil, false } return apiHook, true @@ -169,7 +169,7 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoI if form.Config["is_system_webhook"] != "" { sw, err := strconv.ParseBool(form.Config["is_system_webhook"]) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, "", "Invalid is_system_webhook value") + ctx.APIError(http.StatusUnprocessableEntity, "Invalid is_system_webhook value") return nil, false } isSystemWebhook = sw @@ -215,19 +215,19 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoI } err := w.SetHeaderAuthorization(form.AuthorizationHeader) if err != nil { - ctx.Error(http.StatusInternalServerError, "SetHeaderAuthorization", err) + ctx.APIErrorInternal(err) return nil, false } if w.Type == webhook_module.SLACK { channel, ok := form.Config["channel"] if !ok { - ctx.Error(http.StatusUnprocessableEntity, "", "Missing config option: channel") + ctx.APIError(http.StatusUnprocessableEntity, "Missing config option: channel") return nil, false } channel = strings.TrimSpace(channel) if !webhook_service.IsValidSlackChannel(channel) { - ctx.Error(http.StatusBadRequest, "", "Invalid slack channel name") + ctx.APIError(http.StatusBadRequest, "Invalid slack channel name") return nil, false } @@ -238,17 +238,17 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoI Color: form.Config["color"], }) if err != nil { - ctx.Error(http.StatusInternalServerError, "slack: JSON marshal failed", err) + ctx.APIErrorInternal(err) return nil, false } w.Meta = string(meta) } if err := w.UpdateEvent(); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateEvent", err) + ctx.APIErrorInternal(err) return nil, false } else if err := webhook.CreateWebhook(ctx, w); err != nil { - ctx.Error(http.StatusInternalServerError, "CreateWebhook", err) + ctx.APIErrorInternal(err) return nil, false } return w, true @@ -258,21 +258,21 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, ownerID, repoI func EditSystemHook(ctx *context.APIContext, form *api.EditHookOption, hookID int64) { hook, err := webhook.GetSystemOrDefaultWebhook(ctx, hookID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetSystemOrDefaultWebhook", err) + ctx.APIErrorInternal(err) return } if !editHook(ctx, form, hook) { - ctx.Error(http.StatusInternalServerError, "editHook", err) + ctx.APIErrorInternal(err) return } updated, err := webhook.GetSystemOrDefaultWebhook(ctx, hookID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetSystemOrDefaultWebhook", err) + ctx.APIErrorInternal(err) return } h, err := webhook_service.ToHook(setting.AppURL+"/-/admin", updated) if err != nil { - ctx.Error(http.StatusInternalServerError, "convert.ToHook", err) + ctx.APIErrorInternal(err) return } ctx.JSON(http.StatusOK, h) @@ -328,7 +328,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh } if ct, ok := form.Config["content_type"]; ok { if !webhook.IsValidHookContentType(ct) { - ctx.Error(http.StatusUnprocessableEntity, "", "Invalid content type") + ctx.APIError(http.StatusUnprocessableEntity, "Invalid content type") return false } w.ContentType = webhook.ToHookContentType(ct) @@ -343,7 +343,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh Color: form.Config["color"], }) if err != nil { - ctx.Error(http.StatusInternalServerError, "slack: JSON marshal failed", err) + ctx.APIErrorInternal(err) return false } w.Meta = string(meta) @@ -369,7 +369,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh err := w.SetHeaderAuthorization(form.AuthorizationHeader) if err != nil { - ctx.Error(http.StatusInternalServerError, "SetHeaderAuthorization", err) + ctx.APIErrorInternal(err) return false } @@ -391,7 +391,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh w.HookEvents[webhook_module.HookEventPullRequestSync] = pullHook(form.Events, string(webhook_module.HookEventPullRequestSync)) if err := w.UpdateEvent(); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateEvent", err) + ctx.APIErrorInternal(err) return false } @@ -400,7 +400,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh } if err := webhook.UpdateWebhook(ctx, w); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateWebhook", err) + ctx.APIErrorInternal(err) return false } return true @@ -410,9 +410,9 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *webhook.Webh func DeleteOwnerHook(ctx *context.APIContext, owner *user_model.User, hookID int64) { if err := webhook.DeleteWebhookByOwnerID(ctx, owner.ID, hookID); err != nil { if webhook.IsErrWebhookNotExist(err) { - ctx.NotFound() + ctx.APIErrorNotFound() } else { - ctx.Error(http.StatusInternalServerError, "DeleteWebhookByOwnerID", err) + ctx.APIErrorInternal(err) } return } diff --git a/routers/common/markup.go b/routers/common/markup.go index 533b546a2a106..60bf0dba5467c 100644 --- a/routers/common/markup.go +++ b/routers/common/markup.go @@ -39,7 +39,7 @@ func RenderMarkup(ctx *context.Base, ctxRepo *context.Repository, mode, text, ur rctx := renderhelper.NewRenderContextSimpleDocument(ctx, baseLink).WithUseAbsoluteLink(true). WithMarkupType(markdown.MarkupName) if err := markdown.RenderRaw(rctx, strings.NewReader(text), ctx.Resp); err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) } return } @@ -88,15 +88,15 @@ func RenderMarkup(ctx *context.Base, ctxRepo *context.Repository, mode, text, ur }) rctx = rctx.WithMarkupType("").WithRelativePath(filePath) // render the repo file content by its extension default: - ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", mode)) + ctx.HTTPError(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", mode)) return } rctx = rctx.WithUseAbsoluteLink(true) if err := markup.Render(rctx, strings.NewReader(text), ctx.Resp); err != nil { if errors.Is(err, util.ErrInvalidArgument) { - ctx.Error(http.StatusUnprocessableEntity, err.Error()) + ctx.HTTPError(http.StatusUnprocessableEntity, err.Error()) } else { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) } return } diff --git a/routers/web/admin/auths.go b/routers/web/admin/auths.go index 249347e8352f3..2b3bf1f77d774 100644 --- a/routers/web/admin/auths.go +++ b/routers/web/admin/auths.go @@ -291,7 +291,7 @@ func NewAuthSourcePost(ctx *context.Context) { return } default: - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } ctx.Data["HasTLS"] = hasTLS @@ -413,7 +413,7 @@ func EditAuthSourcePost(ctx *context.Context) { return } default: - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } diff --git a/routers/web/admin/emails.go b/routers/web/admin/emails.go index 23ddfa583a14f..51b3d584f42eb 100644 --- a/routers/web/admin/emails.go +++ b/routers/web/admin/emails.go @@ -116,7 +116,7 @@ func ActivateEmail(ctx *context.Context) { activate, oka := truefalse[ctx.FormString("activate")] if uid == 0 || len(email) == 0 || !okp || !oka { - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 363da8f392919..f07ef989315c6 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -192,7 +192,7 @@ func SignIn(ctx *context.Context) { // SignInPost response for sign in request func SignInPost(ctx *context.Context) { if !setting.Service.EnablePasswordSignInForm { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -456,7 +456,7 @@ func SignUpPost(ctx *context.Context) { // Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true if setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -767,7 +767,7 @@ func handleAccountActivation(ctx *context.Context, user *user_model.User) { } if err := user_model.UpdateUserCols(ctx, user, "is_active", "rands"); err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound("UpdateUserCols", err) + ctx.NotFound(err) } else { ctx.ServerError("UpdateUser", err) } diff --git a/routers/web/auth/linkaccount.go b/routers/web/auth/linkaccount.go index 386241225e09d..b3c61946b91b1 100644 --- a/routers/web/auth/linkaccount.go +++ b/routers/web/auth/linkaccount.go @@ -260,7 +260,7 @@ func LinkAccountPostRegister(ctx *context.Context) { } if setting.Service.DisableRegistration || setting.Service.AllowOnlyInternalRegistration { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } diff --git a/routers/web/auth/oauth2_provider.go b/routers/web/auth/oauth2_provider.go index 6262ad8a6db44..00b5b2db52d5d 100644 --- a/routers/web/auth/oauth2_provider.go +++ b/routers/web/auth/oauth2_provider.go @@ -142,7 +142,7 @@ func IntrospectOAuth(ctx *context.Context) { if err != nil && !auth.IsErrOauthClientIDInvalid(err) { // this is likely a database error; log it and respond without details log.Error("Error retrieving client_id: %v", err) - ctx.Error(http.StatusInternalServerError) + ctx.HTTPError(http.StatusInternalServerError) return } clientIDValid = err == nil && app.ValidateClientSecret([]byte(clientSecret)) @@ -363,7 +363,7 @@ func GrantApplicationOAuth(ctx *context.Context) { form := web.GetForm(ctx).(*forms.GrantApplicationForm) if ctx.Session.Get("client_id") != form.ClientID || ctx.Session.Get("state") != form.State || ctx.Session.Get("redirect_uri") != form.RedirectURI { - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } @@ -440,7 +440,7 @@ func OIDCKeys(ctx *context.Context) { jwk, err := oauth2_provider.DefaultSigningKey.ToJWK() if err != nil { log.Error("Error converting signing key to JWK: %v", err) - ctx.Error(http.StatusInternalServerError) + ctx.HTTPError(http.StatusInternalServerError) return } diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go index 41d37ecb8b300..c3415cccac6d5 100644 --- a/routers/web/auth/openid.go +++ b/routers/web/auth/openid.go @@ -337,7 +337,7 @@ func RegisterOpenIDPost(ctx *context.Context) { ctx.Data["OpenID"] = oid if setting.Service.AllowOnlyInternalRegistration { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } diff --git a/routers/web/auth/password.go b/routers/web/auth/password.go index 614e086f773b0..8dbde85fe6d15 100644 --- a/routers/web/auth/password.go +++ b/routers/web/auth/password.go @@ -53,7 +53,7 @@ func ForgotPasswdPost(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("auth.forgot_password_title") if setting.MailService == nil { - ctx.NotFound("ForgotPasswdPost", nil) + ctx.NotFound(nil) return } ctx.Data["IsResetRequest"] = true @@ -122,7 +122,7 @@ func commonResetPassword(ctx *context.Context) (*user_model.User, *auth.TwoFacto twofa, err := auth.GetTwoFactorByUID(ctx, u.ID) if err != nil { if !auth.IsErrTwoFactorNotEnrolled(err) { - ctx.Error(http.StatusInternalServerError, "CommonResetPassword", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "CommonResetPassword", err.Error()) return nil, nil } } else { @@ -181,7 +181,7 @@ func ResetPasswdPost(ctx *context.Context) { passcode := ctx.FormString("passcode") ok, err := twofa.ValidateTOTP(passcode) if err != nil { - ctx.Error(http.StatusInternalServerError, "ValidateTOTP", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "ValidateTOTP", err.Error()) return } if !ok || twofa.LastUsedPasscode == passcode { diff --git a/routers/web/auth/webauthn.go b/routers/web/auth/webauthn.go index 8dbe34b2b1393..78f6c3b58e62e 100644 --- a/routers/web/auth/webauthn.go +++ b/routers/web/auth/webauthn.go @@ -51,7 +51,7 @@ func WebAuthn(ctx *context.Context) { // WebAuthnPasskeyAssertion submits a WebAuthn challenge for the passkey login to the browser func WebAuthnPasskeyAssertion(ctx *context.Context) { if !setting.Service.EnablePasskeyAuth { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -72,7 +72,7 @@ func WebAuthnPasskeyAssertion(ctx *context.Context) { // WebAuthnPasskeyLogin handles the WebAuthn login process using a Passkey func WebAuthnPasskeyLogin(ctx *context.Context) { if !setting.Service.EnablePasskeyAuth { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } diff --git a/routers/web/devtest/mock_actions.go b/routers/web/devtest/mock_actions.go index f29b8e40465a1..e6539bb31fac6 100644 --- a/routers/web/devtest/mock_actions.go +++ b/routers/web/devtest/mock_actions.go @@ -118,7 +118,7 @@ func MockActionsRunsJobs(ctx *context.Context) { } if doErrorResponse { if mathRand.Float64() > 0.5 { - ctx.Error(http.StatusInternalServerError, "devtest mock error response") + ctx.HTTPError(http.StatusInternalServerError, "devtest mock error response") return } } diff --git a/routers/web/explore/topic.go b/routers/web/explore/topic.go index b4507ba28d4ec..be457df58741c 100644 --- a/routers/web/explore/topic.go +++ b/routers/web/explore/topic.go @@ -25,7 +25,7 @@ func TopicSearch(ctx *context.Context) { topics, total, err := db.FindAndCount[repo_model.Topic](ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError) + ctx.HTTPError(http.StatusInternalServerError) return } diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go index b14272c76aa08..e1e1ec1cfdbc4 100644 --- a/routers/web/explore/user.go +++ b/routers/web/explore/user.go @@ -87,7 +87,7 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions, } if opts.SupportedSortOrders != nil && !opts.SupportedSortOrders.Contains(sortOrder) { - ctx.NotFound("unsupported sort order", nil) + ctx.NotFound(nil) return } diff --git a/routers/web/githttp.go b/routers/web/githttp.go index 5831e6f52366d..8597ffe795d61 100644 --- a/routers/web/githttp.go +++ b/routers/web/githttp.go @@ -21,7 +21,7 @@ func addOwnerRepoGitHTTPRouters(m *web.Router) { if !ctx.IsSigned { // TODO: support digit auth - which would be Authorization header with digit ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea"`) - ctx.Error(http.StatusUnauthorized) + ctx.HTTPError(http.StatusUnauthorized) } } m.Group("/{username}/{reponame}", func() { diff --git a/routers/web/home.go b/routers/web/home.go index 9ad495d54f73c..208cc36dfb833 100644 --- a/routers/web/home.go +++ b/routers/web/home.go @@ -113,5 +113,5 @@ func HomeSitemap(ctx *context.Context) { // NotFound render 404 page func NotFound(ctx *context.Context) { ctx.Data["Title"] = "Page Not Found" - ctx.NotFound("home.NotFound", nil) + ctx.NotFound(nil) } diff --git a/routers/web/org/home.go b/routers/web/org/home.go index 27d1e14d8589d..e3c2dcf0bdd24 100644 --- a/routers/web/org/home.go +++ b/routers/web/org/home.go @@ -29,7 +29,7 @@ func Home(ctx *context.Context) { uname := ctx.PathParam("username") if strings.HasSuffix(uname, ".keys") || strings.HasSuffix(uname, ".gpg") { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } diff --git a/routers/web/org/members.go b/routers/web/org/members.go index 1665a123025ed..7d88d6b1adee8 100644 --- a/routers/web/org/members.go +++ b/routers/web/org/members.go @@ -41,7 +41,7 @@ func Members(ctx *context.Context) { if ctx.Doer != nil { isMember, err := ctx.Org.Organization.IsOrgMember(ctx, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, "IsOrgMember") + ctx.HTTPError(http.StatusInternalServerError, "IsOrgMember") return } opts.IsDoerMember = isMember @@ -50,7 +50,7 @@ func Members(ctx *context.Context) { total, err := organization.CountOrgMembers(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "CountOrgMembers") + ctx.HTTPError(http.StatusInternalServerError, "CountOrgMembers") return } @@ -93,19 +93,19 @@ func MembersAction(ctx *context.Context) { switch ctx.PathParam("action") { case "private": if ctx.Doer.ID != member.ID && !ctx.Org.IsOwner { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } err = organization.ChangeOrgUserStatus(ctx, org.ID, member.ID, false) case "public": if ctx.Doer.ID != member.ID && !ctx.Org.IsOwner { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } err = organization.ChangeOrgUserStatus(ctx, org.ID, member.ID, true) case "remove": if !ctx.Org.IsOwner { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } err = org_service.RemoveOrgUser(ctx, org, member) diff --git a/routers/web/org/org_labels.go b/routers/web/org/org_labels.go index 02eae8052ea2a..ccab2131db207 100644 --- a/routers/web/org/org_labels.go +++ b/routers/web/org/org_labels.go @@ -64,7 +64,7 @@ func UpdateLabel(ctx *context.Context) { if err != nil { switch { case issues_model.IsErrOrgLabelNotExist(err): - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) default: ctx.ServerError("UpdateLabel", err) } diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go index 32da1b41d16d4..985fd2ca45d4d 100644 --- a/routers/web/org/projects.go +++ b/routers/web/org/projects.go @@ -36,7 +36,7 @@ const ( // MustEnableProjects check if projects are enabled in settings func MustEnableProjects(ctx *context.Context) { if unit.TypeProjects.UnitGlobalDisabled() { - ctx.NotFound("EnableProjects", nil) + ctx.NotFound(nil) return } } @@ -77,6 +77,11 @@ func Projects(ctx *context.Context) { return } + if err := project_service.LoadIssueNumbersForProjects(ctx, projects, ctx.Doer); err != nil { + ctx.ServerError("LoadIssueNumbersForProjects", err) + return + } + opTotal, err := db.Count[project_model.Project](ctx, project_model.SearchOptions{ OwnerID: ctx.ContextUser.ID, IsClosed: optional.Some(!isShowClosed), @@ -222,7 +227,7 @@ func DeleteProject(ctx *context.Context) { return } if p.OwnerID != ctx.ContextUser.ID { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -251,7 +256,7 @@ func RenderEditProject(ctx *context.Context) { return } if p.OwnerID != ctx.ContextUser.ID { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -296,7 +301,7 @@ func EditProjectPost(ctx *context.Context) { return } if p.OwnerID != ctx.ContextUser.ID { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -324,7 +329,11 @@ func ViewProject(ctx *context.Context) { return } if project.OwnerID != ctx.ContextUser.ID { - ctx.NotFound("", nil) + ctx.NotFound(nil) + return + } + if err := project.LoadOwner(ctx); err != nil { + ctx.ServerError("LoadOwner", err) return } @@ -340,14 +349,21 @@ func ViewProject(ctx *context.Context) { } assigneeID := ctx.FormInt64("assignee") // TODO: use "optional" but not 0 in the future - issuesMap, err := issues_model.LoadIssuesFromColumnList(ctx, columns, &issues_model.IssuesOptions{ + opts := issues_model.IssuesOptions{ LabelIDs: labelIDs, AssigneeID: optional.Some(assigneeID), - }) + Owner: project.Owner, + Doer: ctx.Doer, + } + + issuesMap, err := project_service.LoadIssuesFromProject(ctx, project, &opts) if err != nil { ctx.ServerError("LoadIssuesOfColumns", err) return } + for _, column := range columns { + column.NumIssues = int64(len(issuesMap[column.ID])) + } if project.CardType != project_model.CardTypeTextOnly { issuesAttachmentMap := make(map[int64][]*attachment_model.Attachment) @@ -593,7 +609,7 @@ func MoveIssues(ctx *context.Context) { return } if project.OwnerID != ctx.ContextUser.ID { - ctx.NotFound("InvalidRepoID", nil) + ctx.NotFound(nil) return } @@ -604,7 +620,7 @@ func MoveIssues(ctx *context.Context) { } if column.ProjectID != project.ID { - ctx.NotFound("ColumnNotInProject", nil) + ctx.NotFound(nil) return } diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 26031029d662f..aeea3708b2aa7 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -74,7 +74,7 @@ func TeamsAction(ctx *context.Context) { switch ctx.PathParam("action") { case "join": if !ctx.Org.IsOwner { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } err = org_service.AddTeamMember(ctx, ctx.Org.Team, ctx.Doer) @@ -96,7 +96,7 @@ func TeamsAction(ctx *context.Context) { return case "remove": if !ctx.Org.IsOwner { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -123,7 +123,7 @@ func TeamsAction(ctx *context.Context) { return case "add": if !ctx.Org.IsOwner { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } uname := strings.ToLower(ctx.FormString("uname")) @@ -167,7 +167,7 @@ func TeamsAction(ctx *context.Context) { page = "team" case "remove_invite": if !ctx.Org.IsOwner { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -228,7 +228,7 @@ func checkIsOrgMemberAndRedirect(ctx *context.Context, defaultRedirect string) { // TeamsRepoAction operate team's repository func TeamsRepoAction(ctx *context.Context) { if !ctx.Org.IsOwner { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -568,7 +568,7 @@ func TeamInvite(ctx *context.Context) { invite, org, team, inviter, err := getTeamInviteFromContext(ctx) if err != nil { if org_model.IsErrTeamInviteNotFound(err) { - ctx.NotFound("ErrTeamInviteNotFound", err) + ctx.NotFound(err) } else { ctx.ServerError("getTeamInviteFromContext", err) } @@ -589,7 +589,7 @@ func TeamInvitePost(ctx *context.Context) { invite, org, team, _, err := getTeamInviteFromContext(ctx) if err != nil { if org_model.IsErrTeamInviteNotFound(err) { - ctx.NotFound("ErrTeamInviteNotFound", err) + ctx.NotFound(err) } else { ctx.ServerError("getTeamInviteFromContext", err) } diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index 539c4b6ed003c..9a5b3398d7835 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -45,18 +45,18 @@ type Workflow struct { // MustEnableActions check if actions are enabled in settings func MustEnableActions(ctx *context.Context) { if !setting.Actions.Enabled { - ctx.NotFound("MustEnableActions", nil) + ctx.NotFound(nil) return } if unit.TypeActions.UnitGlobalDisabled() { - ctx.NotFound("MustEnableActions", nil) + ctx.NotFound(nil) return } if ctx.Repo.Repository != nil { if !ctx.Repo.CanRead(unit.TypeActions) { - ctx.NotFound("MustEnableActions", nil) + ctx.NotFound(nil) return } } @@ -88,7 +88,7 @@ func List(ctx *context.Context) { func WorkflowDispatchInputs(ctx *context.Context) { ref := ctx.FormString("ref") if ref == "" { - ctx.NotFound("WorkflowDispatchInputs: no ref", nil) + ctx.NotFound(nil) return } // get target commit of run from specified ref diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index 0e71ce6ff83be..b27f8e0e7a602 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -277,7 +277,7 @@ func ViewPost(ctx *context_module.Context) { if task != nil { steps, logs, err := convertToViewModel(ctx, req.LogCursors, task) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } resp.State.CurrentJob.Steps = append(resp.State.CurrentJob.Steps, steps...) @@ -381,7 +381,7 @@ func Rerun(ctx *context_module.Context) { run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } @@ -399,7 +399,7 @@ func Rerun(ctx *context_module.Context) { run.Started = 0 run.Stopped = 0 if err := actions_model.UpdateRun(ctx, run, "started", "stopped", "previous_duration"); err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } } @@ -414,7 +414,7 @@ func Rerun(ctx *context_module.Context) { // if the job has needs, it should be set to "blocked" status to wait for other jobs shouldBlock := len(j.Needs) > 0 if err := rerunJob(ctx, j, shouldBlock); err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } } @@ -428,7 +428,7 @@ func Rerun(ctx *context_module.Context) { // jobs other than the specified one should be set to "blocked" status shouldBlock := j.JobID != job.JobID if err := rerunJob(ctx, j, shouldBlock); err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } } @@ -470,29 +470,29 @@ func Logs(ctx *context_module.Context) { return } if job.TaskID == 0 { - ctx.Error(http.StatusNotFound, "job is not started") + ctx.HTTPError(http.StatusNotFound, "job is not started") return } err := job.LoadRun(ctx) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } task, err := actions_model.GetTaskByID(ctx, job.TaskID) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } if task.LogExpired { - ctx.Error(http.StatusNotFound, "logs have been cleaned up") + ctx.HTTPError(http.StatusNotFound, "logs have been cleaned up") return } reader, err := actions.OpenLogs(ctx, task.LogInStorage, task.LogFilename) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } defer reader.Close() @@ -542,7 +542,7 @@ func Cancel(ctx *context_module.Context) { } return nil }); err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } @@ -578,7 +578,7 @@ func Approve(ctx *context_module.Context) { } return nil }); err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } @@ -594,20 +594,20 @@ func getRunJobs(ctx *context_module.Context, runIndex, jobIndex int64) (*actions run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, err.Error()) + ctx.HTTPError(http.StatusNotFound, err.Error()) return nil, nil } - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return nil, nil } run.Repo = ctx.Repo.Repository jobs, err := actions_model.GetRunJobsByRunID(ctx, run.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return nil, nil } if len(jobs) == 0 { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return nil, nil } @@ -633,7 +633,7 @@ func ArtifactsDeleteView(ctx *context_module.Context) { return } if err = actions_model.SetArtifactNeedDelete(ctx, run.ID, artifactName); err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } ctx.JSON(http.StatusOK, struct{}{}) @@ -646,10 +646,10 @@ func ArtifactsDownloadView(ctx *context_module.Context) { run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex) if err != nil { if errors.Is(err, util.ErrNotExist) { - ctx.Error(http.StatusNotFound, err.Error()) + ctx.HTTPError(http.StatusNotFound, err.Error()) return } - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } @@ -658,18 +658,18 @@ func ArtifactsDownloadView(ctx *context_module.Context) { ArtifactName: artifactName, }) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } if len(artifacts) == 0 { - ctx.Error(http.StatusNotFound, "artifact not found") + ctx.HTTPError(http.StatusNotFound, "artifact not found") return } // if artifacts status is not uploaded-confirmed, treat it as not found for _, art := range artifacts { if art.Status != actions_model.ArtifactStatusUploadConfirmed { - ctx.Error(http.StatusNotFound, "artifact not found") + ctx.HTTPError(http.StatusNotFound, "artifact not found") return } } @@ -679,7 +679,7 @@ func ArtifactsDownloadView(ctx *context_module.Context) { if len(artifacts) == 1 && actions.IsArtifactV4(artifacts[0]) { err := actions.DownloadArtifactV4(ctx.Base, artifacts[0]) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } return @@ -692,7 +692,7 @@ func ArtifactsDownloadView(ctx *context_module.Context) { for _, art := range artifacts { f, err := storage.ActionsArtifacts.Open(art.StoragePath) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } @@ -700,7 +700,7 @@ func ArtifactsDownloadView(ctx *context_module.Context) { if art.ContentEncoding == "gzip" { r, err = gzip.NewReader(f) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } } else { @@ -710,11 +710,11 @@ func ArtifactsDownloadView(ctx *context_module.Context) { w, err := writer.Create(art.ArtifactPath) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } if _, err := io.Copy(w, r); err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } } diff --git a/routers/web/repo/attachment.go b/routers/web/repo/attachment.go index f8e51521be525..9eda926dad823 100644 --- a/routers/web/repo/attachment.go +++ b/routers/web/repo/attachment.go @@ -34,13 +34,13 @@ func UploadReleaseAttachment(ctx *context.Context) { // UploadAttachment response for uploading attachments func uploadAttachment(ctx *context.Context, repoID int64, allowedTypes string) { if !setting.Attachment.Enabled { - ctx.Error(http.StatusNotFound, "attachment is not enabled") + ctx.HTTPError(http.StatusNotFound, "attachment is not enabled") return } file, header, err := ctx.Req.FormFile("file") if err != nil { - ctx.Error(http.StatusInternalServerError, fmt.Sprintf("FormFile: %v", err)) + ctx.HTTPError(http.StatusInternalServerError, fmt.Sprintf("FormFile: %v", err)) return } defer file.Close() @@ -52,10 +52,10 @@ func uploadAttachment(ctx *context.Context, repoID int64, allowedTypes string) { }) if err != nil { if upload.IsErrFileTypeForbidden(err) { - ctx.Error(http.StatusBadRequest, err.Error()) + ctx.HTTPError(http.StatusBadRequest, err.Error()) return } - ctx.Error(http.StatusInternalServerError, fmt.Sprintf("NewAttachment: %v", err)) + ctx.HTTPError(http.StatusInternalServerError, fmt.Sprintf("NewAttachment: %v", err)) return } @@ -70,16 +70,16 @@ func DeleteAttachment(ctx *context.Context) { file := ctx.FormString("file") attach, err := repo_model.GetAttachmentByUUID(ctx, file) if err != nil { - ctx.Error(http.StatusBadRequest, err.Error()) + ctx.HTTPError(http.StatusBadRequest, err.Error()) return } if !ctx.IsSigned || (ctx.Doer.ID != attach.UploaderID) { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } err = repo_model.DeleteAttachment(ctx, attach, true) if err != nil { - ctx.Error(http.StatusInternalServerError, fmt.Sprintf("DeleteAttachment: %v", err)) + ctx.HTTPError(http.StatusInternalServerError, fmt.Sprintf("DeleteAttachment: %v", err)) return } ctx.JSON(http.StatusOK, map[string]string{ @@ -92,7 +92,7 @@ func ServeAttachment(ctx *context.Context, uuid string) { attach, err := repo_model.GetAttachmentByUUID(ctx, uuid) if err != nil { if repo_model.IsErrAttachmentNotExist(err) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) } else { ctx.ServerError("GetAttachmentByUUID", err) } @@ -107,17 +107,17 @@ func ServeAttachment(ctx *context.Context, uuid string) { if repository == nil { // If not linked if !(ctx.IsSigned && attach.UploaderID == ctx.Doer.ID) { // We block if not the uploader - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } } else { // If we have the repository we check access perm, err := access_model.GetUserRepoPermission(ctx, repository, ctx.Doer) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "GetUserRepoPermission", err.Error()) return } if !perm.CanRead(unitType) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } } diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index 27de35efb23ac..eddfcab07824e 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -42,7 +42,7 @@ type blameRow struct { func RefBlame(ctx *context.Context) { fileName := ctx.Repo.TreePath if len(fileName) == 0 { - ctx.NotFound("Blame FileName", nil) + ctx.NotFound(nil) return } @@ -99,7 +99,7 @@ func RefBlame(ctx *context.Context) { ctx.Data["NumLines"], err = blob.GetBlobLineCount() if err != nil { - ctx.NotFound("GetBlobLineCount", err) + ctx.NotFound(err) return } @@ -107,7 +107,7 @@ func RefBlame(ctx *context.Context) { result, err := performBlame(ctx, ctx.Repo.Repository.RepoPath(), ctx.Repo.Commit, fileName, bypassBlameIgnore) if err != nil { - ctx.NotFound("CreateBlameReader", err) + ctx.NotFound(err) return } @@ -221,7 +221,7 @@ func processBlameParts(ctx *context.Context, blameParts []*git.BlamePart) map[st commit, err = ctx.Repo.GitRepo.GetCommit(sha) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("Repo.GitRepo.GetCommit", err) + ctx.NotFound(err) } else { ctx.ServerError("Repo.GitRepo.GetCommit", err) } diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index 6f8d4d9959580..5d963eff66930 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -178,7 +178,7 @@ func jsonRedirectBranches(ctx *context.Context) { func CreateBranch(ctx *context.Context) { form := web.GetForm(ctx).(*forms.NewBranchForm) if !ctx.Repo.CanCreateBranch() { - ctx.NotFound("CreateBranch", nil) + ctx.NotFound(nil) return } diff --git a/routers/web/repo/cherry_pick.go b/routers/web/repo/cherry_pick.go index 616bb8c6cbb10..ec50e1435ef36 100644 --- a/routers/web/repo/cherry_pick.go +++ b/routers/web/repo/cherry_pick.go @@ -28,7 +28,7 @@ func CherryPick(ctx *context.Context) { cherryPickCommit, err := ctx.Repo.GitRepo.GetCommit(ctx.PathParam("sha")) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("Missing Commit", err) + ctx.NotFound(err) return } ctx.ServerError("GetCommit", err) @@ -148,7 +148,7 @@ func CherryPickPost(ctx *context.Context) { if form.Revert { if err := git.GetReverseRawDiff(ctx, ctx.Repo.Repository.RepoPath(), sha, buf); err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("GetRawDiff", errors.New("commit "+ctx.PathParam("sha")+" does not exist.")) + ctx.NotFound(errors.New("commit " + ctx.PathParam("sha") + " does not exist.")) return } ctx.ServerError("GetRawDiff", err) @@ -157,7 +157,7 @@ func CherryPickPost(ctx *context.Context) { } else { if err := git.GetRawDiff(ctx.Repo.GitRepo, sha, git.RawDiffType("patch"), buf); err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("GetRawDiff", errors.New("commit "+ctx.PathParam("sha")+" does not exist.")) + ctx.NotFound(errors.New("commit " + ctx.PathParam("sha") + " does not exist.")) return } ctx.ServerError("GetRawDiff", err) diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 12c3d9db52d68..9c12ef9297813 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -59,7 +59,7 @@ func RefCommits(ctx *context.Context) { func Commits(ctx *context.Context) { ctx.Data["PageIsCommits"] = true if ctx.Repo.Commit == nil { - ctx.NotFound("Commit not found", nil) + ctx.NotFound(nil) return } ctx.Data["PageIsViewCode"] = true @@ -226,7 +226,7 @@ func FileHistory(ctx *context.Context) { ctx.ServerError("FileCommitsCount", err) return } else if commitsCount == 0 { - ctx.NotFound("FileCommitsCount", nil) + ctx.NotFound(nil) return } @@ -297,7 +297,7 @@ func Diff(ctx *context.Context) { commit, err := gitRepo.GetCommit(commitID) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("Repo.GitRepo.GetCommit", err) + ctx.NotFound(err) } else { ctx.ServerError("Repo.GitRepo.GetCommit", err) } @@ -324,7 +324,7 @@ func Diff(ctx *context.Context) { FileOnly: fileOnly, }, files...) if err != nil { - ctx.NotFound("GetDiff", err) + ctx.NotFound(err) return } @@ -332,7 +332,7 @@ func Diff(ctx *context.Context) { for i := 0; i < commit.ParentCount(); i++ { sha, err := commit.ParentID(i) if err != nil { - ctx.NotFound("repo.Diff", err) + ctx.NotFound(err) return } parents[i] = sha.String() @@ -347,7 +347,7 @@ func Diff(ctx *context.Context) { if commit.ParentCount() > 0 { parentCommit, err = gitRepo.GetCommit(parents[0]) if err != nil { - ctx.NotFound("GetParentCommit", err) + ctx.NotFound(err) return } } @@ -421,8 +421,7 @@ func RawDiff(ctx *context.Context) { ctx.Resp, ); err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("GetRawDiff", - errors.New("commit "+ctx.PathParam("sha")+" does not exist.")) + ctx.NotFound(errors.New("commit " + ctx.PathParam("sha") + " does not exist.")) return } ctx.ServerError("GetRawDiff", err) diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index cb16a3819a2fd..71bce759a9252 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -258,7 +258,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { ci.HeadUser, err = user_model.GetUserByName(ctx, headInfos[0]) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound("GetUserByName", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetUserByName", err) } @@ -273,7 +273,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { ci.HeadRepo, err = repo_model.GetRepositoryByOwnerAndName(ctx, headInfosSplit[0], headInfosSplit[1]) if err != nil { if repo_model.IsErrRepoNotExist(err) { - ctx.NotFound("GetRepositoryByOwnerAndName", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetRepositoryByOwnerAndName", err) } @@ -281,7 +281,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { } if err := ci.HeadRepo.LoadOwner(ctx); err != nil { if user_model.IsErrUserNotExist(err) { - ctx.NotFound("GetUserByName", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetUserByName", err) } @@ -292,7 +292,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { isSameRepo = ci.HeadRepo.ID == ctx.Repo.Repository.ID } } else { - ctx.NotFound("CompareAndPullRequest", nil) + ctx.NotFound(nil) return nil } ctx.Data["HeadUser"] = ci.HeadUser @@ -318,7 +318,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { } return nil } else { - ctx.NotFound("IsRefExist", nil) + ctx.NotFound(nil) return nil } } @@ -408,7 +408,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { } defer ci.HeadGitRepo.Close() } else { - ctx.NotFound("ParseCompareInfo", nil) + ctx.NotFound(nil) return nil } @@ -430,7 +430,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { baseRepo, permBase) } - ctx.NotFound("ParseCompareInfo", nil) + ctx.NotFound(nil) return nil } @@ -449,7 +449,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { ci.HeadRepo, permHead) } - ctx.NotFound("ParseCompareInfo", nil) + ctx.NotFound(nil) return nil } ctx.Data["CanWriteToHeadRepo"] = permHead.CanWrite(unit.TypeCode) @@ -513,7 +513,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { ctx.Data["HeadBranch"] = ci.HeadBranch headIsCommit = true } else { - ctx.NotFound("IsRefExist", nil) + ctx.NotFound(nil) return nil } } @@ -533,7 +533,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo { baseRepo, permBase) } - ctx.NotFound("ParseCompareInfo", nil) + ctx.NotFound(nil) return nil } @@ -880,7 +880,7 @@ func ExcerptBlob(ctx *context.Context) { chunkSize := gitdiff.BlobExcerptChunkSize commit, err := gitRepo.GetCommit(commitID) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetCommit") + ctx.HTTPError(http.StatusInternalServerError, "GetCommit") return } section := &gitdiff.DiffSection{ @@ -909,7 +909,7 @@ func ExcerptBlob(ctx *context.Context) { idxRight = lastRight } if err != nil { - ctx.Error(http.StatusInternalServerError, "getExcerptLines") + ctx.HTTPError(http.StatusInternalServerError, "getExcerptLines") return } if idxRight > lastRight { diff --git a/routers/web/repo/download.go b/routers/web/repo/download.go index cb1163c70b7ed..060381e9d6136 100644 --- a/routers/web/repo/download.go +++ b/routers/web/repo/download.go @@ -85,7 +85,7 @@ func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) { entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("GetTreeEntryByPath", err) + ctx.NotFound(err) } else { ctx.ServerError("GetTreeEntryByPath", err) } @@ -93,7 +93,7 @@ func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) { } if entry.IsDir() || entry.IsSubModule() { - ctx.NotFound("getBlobForEntry", nil) + ctx.NotFound(nil) return nil, nil } @@ -136,7 +136,7 @@ func DownloadByID(ctx *context.Context) { blob, err := ctx.Repo.GitRepo.GetBlob(ctx.PathParam("sha")) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("GetBlob", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetBlob", err) } @@ -152,7 +152,7 @@ func DownloadByIDOrLFS(ctx *context.Context) { blob, err := ctx.Repo.GitRepo.GetBlob(ctx.PathParam("sha")) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("GetBlob", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetBlob", err) } diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index cc4ffc698ddca..3107d7b849c8d 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -141,19 +141,19 @@ func editFile(ctx *context.Context, isNewFile bool) { // No way to edit a directory online. if entry.IsDir() { - ctx.NotFound("entry.IsDir", nil) + ctx.NotFound(nil) return } blob := entry.Blob() if blob.Size() >= setting.UI.MaxDisplayFileSize { - ctx.NotFound("blob.Size", err) + ctx.NotFound(err) return } dataRc, err := blob.DataAsync() if err != nil { - ctx.NotFound("blob.Data", err) + ctx.NotFound(err) return } @@ -168,7 +168,7 @@ func editFile(ctx *context.Context, isNewFile bool) { // Only some file types are editable online as text. if !typesniffer.DetectContentType(buf).IsRepresentableAsText() { - ctx.NotFound("typesniffer.IsRepresentableAsText", nil) + ctx.NotFound(nil) return } @@ -324,7 +324,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b ctx.RenderWithErr(ctx.Tr("repo.editor.filename_is_invalid", fileErr.Path), tplEditFile, &form) } } else { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) } } else if files_service.IsErrRepoFileAlreadyExists(err) { ctx.Data["Err_TreePath"] = true @@ -334,7 +334,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b if branchErr, ok := err.(git.ErrBranchNotExist); ok { ctx.RenderWithErr(ctx.Tr("repo.editor.branch_does_not_exist", branchErr.Name), tplEditFile, &form) } else { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) } } else if git_model.IsErrBranchAlreadyExists(err) { // For when a user specifies a new branch that already exists @@ -342,7 +342,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b if branchErr, ok := err.(git_model.ErrBranchAlreadyExists); ok { ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplEditFile, &form) } else { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) } } else if files_service.IsErrCommitIDDoesNotMatch(err) { ctx.RenderWithErr(ctx.Tr("repo.editor.commit_id_not_matching"), tplEditFile, &form) @@ -404,22 +404,22 @@ func DiffPreviewPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.EditPreviewDiffForm) treePath := cleanUploadFileName(ctx.Repo.TreePath) if len(treePath) == 0 { - ctx.Error(http.StatusInternalServerError, "file name to diff is invalid") + ctx.HTTPError(http.StatusInternalServerError, "file name to diff is invalid") return } entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treePath) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetTreeEntryByPath: "+err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "GetTreeEntryByPath: "+err.Error()) return } else if entry.IsDir() { - ctx.Error(http.StatusUnprocessableEntity) + ctx.HTTPError(http.StatusUnprocessableEntity) return } diff, err := files_service.GetDiffPreview(ctx, ctx.Repo.Repository, ctx.Repo.BranchName, treePath, form.Content) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetDiffPreview: "+err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "GetDiffPreview: "+err.Error()) return } @@ -545,14 +545,14 @@ func DeleteFilePost(ctx *context.Context) { if branchErr, ok := err.(git.ErrBranchNotExist); ok { ctx.RenderWithErr(ctx.Tr("repo.editor.branch_does_not_exist", branchErr.Name), tplDeleteFile, &form) } else { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) } } else if git_model.IsErrBranchAlreadyExists(err) { // For when a user specifies a new branch that already exists if branchErr, ok := err.(git_model.ErrBranchAlreadyExists); ok { ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplDeleteFile, &form) } else { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) } } else if files_service.IsErrCommitIDDoesNotMatch(err) || git.IsErrPushOutOfDate(err) { ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_deleting", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(ctx.Repo.CommitID)), tplDeleteFile, &form) @@ -751,7 +751,7 @@ func UploadFilePost(ctx *context.Context) { case git.EntryModeBlob: ctx.RenderWithErr(ctx.Tr("repo.editor.directory_is_a_file", fileErr.Path), tplUploadFile, &form) default: - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) } } else if files_service.IsErrRepoFileAlreadyExists(err) { ctx.Data["Err_TreePath"] = true @@ -815,7 +815,7 @@ func cleanUploadFileName(name string) string { func UploadFileToServer(ctx *context.Context) { file, header, err := ctx.Req.FormFile("file") if err != nil { - ctx.Error(http.StatusInternalServerError, fmt.Sprintf("FormFile: %v", err)) + ctx.HTTPError(http.StatusInternalServerError, fmt.Sprintf("FormFile: %v", err)) return } defer file.Close() @@ -828,19 +828,19 @@ func UploadFileToServer(ctx *context.Context) { err = upload.Verify(buf, header.Filename, setting.Repository.Upload.AllowedTypes) if err != nil { - ctx.Error(http.StatusBadRequest, err.Error()) + ctx.HTTPError(http.StatusBadRequest, err.Error()) return } name := cleanUploadFileName(header.Filename) if len(name) == 0 { - ctx.Error(http.StatusInternalServerError, "Upload file name is invalid") + ctx.HTTPError(http.StatusInternalServerError, "Upload file name is invalid") return } upload, err := repo_model.NewUpload(ctx, name, buf, file) if err != nil { - ctx.Error(http.StatusInternalServerError, fmt.Sprintf("NewUpload: %v", err)) + ctx.HTTPError(http.StatusInternalServerError, fmt.Sprintf("NewUpload: %v", err)) return } @@ -859,7 +859,7 @@ func RemoveUploadFileFromServer(ctx *context.Context) { } if err := repo_model.DeleteUploadByUUID(ctx, form.File); err != nil { - ctx.Error(http.StatusInternalServerError, fmt.Sprintf("DeleteUploadByUUID: %v", err)) + ctx.HTTPError(http.StatusInternalServerError, fmt.Sprintf("DeleteUploadByUUID: %v", err)) return } diff --git a/routers/web/repo/fork.go b/routers/web/repo/fork.go index 786b5d7e43500..36e64bfee31ae 100644 --- a/routers/web/repo/fork.go +++ b/routers/web/repo/fork.go @@ -37,7 +37,7 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository { if forkRepo.IsEmpty { log.Trace("Empty repository %-v", forkRepo) - ctx.NotFound("getForkRepository", nil) + ctx.NotFound(nil) return nil } @@ -189,7 +189,7 @@ func ForkPost(ctx *context.Context) { ctx.ServerError("CanCreateOrgRepo", err) return } else if !isAllowedToFork { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } } diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go index 6b2a7fd07667e..e27040edc6512 100644 --- a/routers/web/repo/githttp.go +++ b/routers/web/repo/githttp.go @@ -147,7 +147,7 @@ func httpBase(ctx *context.Context) *serviceHandler { if !ctx.IsSigned { // TODO: support digit auth - which would be Authorization header with digit ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea"`) - ctx.Error(http.StatusUnauthorized) + ctx.HTTPError(http.StatusUnauthorized) return nil } diff --git a/routers/web/repo/helper.go b/routers/web/repo/helper.go index 3bf064c1e386d..7b92cba0fd30b 100644 --- a/routers/web/repo/helper.go +++ b/routers/web/repo/helper.go @@ -12,7 +12,7 @@ func HandleGitError(ctx *context.Context, msg string, err error) { if git.IsErrNotExist(err) { ctx.Data["NotFoundPrompt"] = ctx.Locale.Tr("repo.tree_path_not_found", ctx.Repo.TreePath, ctx.Repo.RefTypeNameSubURL()) ctx.Data["NotFoundGoBackURL"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() - ctx.NotFound(msg, err) + ctx.NotFound(err) } else { ctx.ServerError(msg, err) } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index f150897a2d72f..dbbe29a3c3f4f 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -91,7 +91,7 @@ func MustAllowUserComment(ctx *context.Context) { func MustEnableIssues(ctx *context.Context) { if !ctx.Repo.CanRead(unit.TypeIssues) && !ctx.Repo.CanRead(unit.TypeExternalTracker) { - ctx.NotFound("MustEnableIssues", nil) + ctx.NotFound(nil) return } @@ -105,7 +105,7 @@ func MustEnableIssues(ctx *context.Context) { // MustAllowPulls check if repository enable pull requests and user have right to do that func MustAllowPulls(ctx *context.Context) { if !ctx.Repo.Repository.CanEnablePulls() || !ctx.Repo.CanRead(unit.TypePullRequests) { - ctx.NotFound("MustAllowPulls", nil) + ctx.NotFound(nil) return } @@ -201,7 +201,7 @@ func GetActionIssue(ctx *context.Context) *issues_model.Issue { func checkIssueRights(ctx *context.Context, issue *issues_model.Issue) { if issue.IsPull && !ctx.Repo.CanRead(unit.TypePullRequests) || !issue.IsPull && !ctx.Repo.CanRead(unit.TypeIssues) { - ctx.NotFound("IssueOrPullRequestUnitNotAllowed", nil) + ctx.NotFound(nil) } } @@ -229,11 +229,11 @@ func getActionIssues(ctx *context.Context) issues_model.IssueList { prUnitEnabled := ctx.Repo.CanRead(unit.TypePullRequests) for _, issue := range issues { if issue.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("some issue's RepoID is incorrect", errors.New("some issue's RepoID is incorrect")) + ctx.NotFound(errors.New("some issue's RepoID is incorrect")) return nil } if issue.IsPull && !prUnitEnabled || !issue.IsPull && !issueUnitEnabled { - ctx.NotFound("IssueOrPullRequestUnitNotAllowed", nil) + ctx.NotFound(nil) return nil } if err = issue.LoadAttributes(ctx); err != nil { @@ -249,9 +249,9 @@ func GetIssueInfo(ctx *context.Context) { issue, err := issues_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "GetIssueByIndex", err.Error()) } return } @@ -259,13 +259,13 @@ func GetIssueInfo(ctx *context.Context) { if issue.IsPull { // Need to check if Pulls are enabled and we can read Pulls if !ctx.Repo.Repository.CanEnablePulls() || !ctx.Repo.CanRead(unit.TypePullRequests) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } } else { // Need to check if Issues are enabled and we can read Issues if !ctx.Repo.CanRead(unit.TypeIssues) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } } @@ -284,13 +284,13 @@ func UpdateIssueTitle(ctx *context.Context) { } if !ctx.IsSigned || (!issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } title := ctx.FormTrim("title") if len(title) == 0 { - ctx.Error(http.StatusNoContent) + ctx.HTTPError(http.StatusNoContent) return } @@ -312,7 +312,7 @@ func UpdateIssueRef(ctx *context.Context) { } if !ctx.IsSigned || (!issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) || issue.IsPull { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -336,7 +336,7 @@ func UpdateIssueContent(ctx *context.Context) { } if !ctx.IsSigned || (ctx.Doer.ID != issue.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -382,21 +382,21 @@ func UpdateIssueDeadline(ctx *context.Context) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound("GetIssueByIndex", err) + ctx.NotFound(err) } else { - ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "GetIssueByIndex", err.Error()) } return } if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.Error(http.StatusForbidden, "", "Not repo writer") + ctx.HTTPError(http.StatusForbidden, "", "Not repo writer") return } deadlineUnix, _ := common.ParseDeadlineDateToEndOfDay(ctx.FormString("deadline")) if err := issues_model.UpdateIssueDeadline(ctx, issue, deadlineUnix, ctx.Doer); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "UpdateIssueDeadline", err.Error()) return } @@ -497,7 +497,7 @@ func ChangeIssueReaction(ctx *context.Context) { } } - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -540,7 +540,7 @@ func ChangeIssueReaction(ctx *context.Context) { log.Trace("Reaction for issue removed: %d/%d", ctx.Repo.Repository.ID, issue.ID) default: - ctx.NotFound(fmt.Sprintf("Unknown action %s", ctx.PathParam("action")), nil) + ctx.NotFound(nil) return } diff --git a/routers/web/repo/issue_comment.go b/routers/web/repo/issue_comment.go index 8564c613de04d..bc84950701726 100644 --- a/routers/web/repo/issue_comment.go +++ b/routers/web/repo/issue_comment.go @@ -53,7 +53,7 @@ func NewComment(ctx *context.Context) { } } - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -224,17 +224,17 @@ func UpdateCommentContent(ctx *context.Context) { } if comment.Issue.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{}) + ctx.NotFound(issues_model.ErrCommentNotExist{}) return } if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } if !comment.Type.HasContentSupport() { - ctx.Error(http.StatusNoContent) + ctx.HTTPError(http.StatusNoContent) return } @@ -302,15 +302,15 @@ func DeleteComment(ctx *context.Context) { } if comment.Issue.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{}) + ctx.NotFound(issues_model.ErrCommentNotExist{}) return } if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } else if !comment.Type.HasContentSupport() { - ctx.Error(http.StatusNoContent) + ctx.HTTPError(http.StatusNoContent) return } @@ -337,7 +337,7 @@ func ChangeCommentReaction(ctx *context.Context) { } if comment.Issue.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{}) + ctx.NotFound(issues_model.ErrCommentNotExist{}) return } @@ -360,12 +360,12 @@ func ChangeCommentReaction(ctx *context.Context) { } } - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } if !comment.Type.HasContentSupport() { - ctx.Error(http.StatusNoContent) + ctx.HTTPError(http.StatusNoContent) return } @@ -403,7 +403,7 @@ func ChangeCommentReaction(ctx *context.Context) { log.Trace("Reaction for comment removed: %d/%d/%d", ctx.Repo.Repository.ID, comment.Issue.ID, comment.ID) default: - ctx.NotFound(fmt.Sprintf("Unknown action %s", ctx.PathParam("action")), nil) + ctx.NotFound(nil) return } @@ -442,12 +442,12 @@ func GetCommentAttachments(ctx *context.Context) { } if comment.Issue.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{}) + ctx.NotFound(issues_model.ErrCommentNotExist{}) return } if !ctx.Repo.Permission.CanReadIssuesOrPulls(comment.Issue.IsPull) { - ctx.NotFound("CanReadIssuesOrPulls", issues_model.ErrCommentNotExist{}) + ctx.NotFound(issues_model.ErrCommentNotExist{}) return } diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go index 13c6d89b6ec44..c2c208736c735 100644 --- a/routers/web/repo/issue_content_history.go +++ b/routers/web/repo/issue_content_history.go @@ -186,7 +186,7 @@ func SoftDeleteContentHistory(ctx *context.Context) { return } if ctx.Doer == nil { - ctx.NotFound("Require SignIn", nil) + ctx.NotFound(nil) return } @@ -202,12 +202,12 @@ func SoftDeleteContentHistory(ctx *context.Context) { return } if history.IssueID != issue.ID { - ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{}) + ctx.NotFound(issues_model.ErrCommentNotExist{}) return } if commentID != 0 { if history.CommentID != commentID { - ctx.NotFound("CompareCommentID", issues_model.ErrCommentNotExist{}) + ctx.NotFound(issues_model.ErrCommentNotExist{}) return } @@ -216,7 +216,7 @@ func SoftDeleteContentHistory(ctx *context.Context) { return } if comment.IssueID != issue.ID { - ctx.NotFound("CompareIssueID", issues_model.ErrCommentNotExist{}) + ctx.NotFound(issues_model.ErrCommentNotExist{}) return } } diff --git a/routers/web/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go index 0f6787386d99a..73298958c0559 100644 --- a/routers/web/repo/issue_dependency.go +++ b/routers/web/repo/issue_dependency.go @@ -23,7 +23,7 @@ func AddDependency(ctx *context.Context) { // Check if the Repo is allowed to have dependencies if !ctx.Repo.CanCreateIssueDependencies(ctx, ctx.Doer, issue.IsPull) { - ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies") + ctx.HTTPError(http.StatusForbidden, "CanCreateIssueDependencies") return } @@ -97,7 +97,7 @@ func RemoveDependency(ctx *context.Context) { // Check if the Repo is allowed to have dependencies if !ctx.Repo.CanCreateIssueDependencies(ctx, ctx.Doer, issue.IsPull) { - ctx.Error(http.StatusForbidden, "CanCreateIssueDependencies") + ctx.HTTPError(http.StatusForbidden, "CanCreateIssueDependencies") return } @@ -119,7 +119,7 @@ func RemoveDependency(ctx *context.Context) { case "blocking": depType = issues_model.DependencyTypeBlocking default: - ctx.Error(http.StatusBadRequest, "GetDependecyType") + ctx.HTTPError(http.StatusBadRequest, "GetDependecyType") return } diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go index 5ef6b09faa0d8..62c0128f19f64 100644 --- a/routers/web/repo/issue_label.go +++ b/routers/web/repo/issue_label.go @@ -131,7 +131,7 @@ func UpdateLabel(ctx *context.Context) { if err != nil { switch { case issues_model.IsErrRepoLabelNotExist(err): - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) default: ctx.ServerError("UpdateLabel", err) } @@ -180,7 +180,7 @@ func UpdateIssueLabel(ctx *context.Context) { label, err := issues_model.GetLabelByID(ctx, ctx.FormInt64("id")) if err != nil { if issues_model.IsErrRepoLabelNotExist(err) { - ctx.Error(http.StatusNotFound, "GetLabelByID") + ctx.HTTPError(http.StatusNotFound, "GetLabelByID") } else { ctx.ServerError("GetLabelByID", err) } @@ -221,7 +221,7 @@ func UpdateIssueLabel(ctx *context.Context) { } default: log.Warn("Unrecognized action: %s", action) - ctx.Error(http.StatusInternalServerError) + ctx.HTTPError(http.StatusInternalServerError) return } diff --git a/routers/web/repo/issue_list.go b/routers/web/repo/issue_list.go index 2f615a100e3d0..a65ae77795584 100644 --- a/routers/web/repo/issue_list.go +++ b/routers/web/repo/issue_list.go @@ -46,7 +46,7 @@ func retrieveProjectsForIssueList(ctx *context.Context, repo *repo_model.Reposit func SearchIssues(ctx *context.Context) { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, err.Error()) + ctx.HTTPError(http.StatusUnprocessableEntity, err.Error()) return } @@ -84,9 +84,9 @@ func SearchIssues(ctx *context.Context) { owner, err := user_model.GetUserByName(ctx, ctx.FormString("owner")) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusBadRequest, "Owner not found", err.Error()) + ctx.HTTPError(http.StatusBadRequest, "Owner not found", err.Error()) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "GetUserByName", err.Error()) } return } @@ -97,15 +97,15 @@ func SearchIssues(ctx *context.Context) { } if ctx.FormString("team") != "" { if ctx.FormString("owner") == "" { - ctx.Error(http.StatusBadRequest, "", "Owner organisation is required for filtering on team") + ctx.HTTPError(http.StatusBadRequest, "", "Owner organisation is required for filtering on team") return } team, err := organization.GetTeam(ctx, opts.OwnerID, ctx.FormString("team")) if err != nil { if organization.IsErrTeamNotExist(err) { - ctx.Error(http.StatusBadRequest, "Team not found", err.Error()) + ctx.HTTPError(http.StatusBadRequest, "Team not found", err.Error()) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByName", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "GetUserByName", err.Error()) } return } @@ -118,7 +118,7 @@ func SearchIssues(ctx *context.Context) { } repoIDs, _, err = repo_model.SearchRepositoryIDs(ctx, opts) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchRepositoryIDs", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "SearchRepositoryIDs", err.Error()) return } if len(repoIDs) == 0 { @@ -149,7 +149,7 @@ func SearchIssues(ctx *context.Context) { } includedAnyLabels, err = issues_model.GetLabelIDsByNames(ctx, includedLabelNames) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetLabelIDsByNames", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "GetLabelIDsByNames", err.Error()) return } } @@ -163,7 +163,7 @@ func SearchIssues(ctx *context.Context) { } includedMilestones, err = issues_model.GetMilestoneIDsByNames(ctx, includedMilestoneNames) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetMilestoneIDsByNames", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "GetMilestoneIDsByNames", err.Error()) return } } @@ -230,12 +230,12 @@ func SearchIssues(ctx *context.Context) { ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchIssues", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "SearchIssues", err.Error()) return } issues, err := issues_model.GetIssuesByIDs(ctx, ids, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindIssuesByIDs", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "FindIssuesByIDs", err.Error()) return } @@ -251,12 +251,12 @@ func getUserIDForFilter(ctx *context.Context, queryName string) int64 { user, err := user_model.GetUserByName(ctx, userName) if user_model.IsErrUserNotExist(err) { - ctx.NotFound("", err) + ctx.NotFound(err) return 0 } if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return 0 } @@ -269,7 +269,7 @@ func getUserIDForFilter(ctx *context.Context, queryName string) int64 { func SearchRepoIssuesJSON(ctx *context.Context) { before, since, err := context.GetQueryBeforeSince(ctx.Base) if err != nil { - ctx.Error(http.StatusUnprocessableEntity, err.Error()) + ctx.HTTPError(http.StatusUnprocessableEntity, err.Error()) return } @@ -299,7 +299,7 @@ func SearchRepoIssuesJSON(ctx *context.Context) { continue } if !issues_model.IsErrMilestoneNotExist(err) { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } id, err := strconv.ParseInt(part[i], 10, 64) @@ -314,7 +314,7 @@ func SearchRepoIssuesJSON(ctx *context.Context) { if issues_model.IsErrMilestoneNotExist(err) { continue } - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) } } @@ -384,12 +384,12 @@ func SearchRepoIssuesJSON(ctx *context.Context) { ids, total, err := issue_indexer.SearchIssues(ctx, searchOpt) if err != nil { - ctx.Error(http.StatusInternalServerError, "SearchIssues", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "SearchIssues", err.Error()) return } issues, err := issues_model.GetIssuesByIDs(ctx, ids, true) if err != nil { - ctx.Error(http.StatusInternalServerError, "FindIssuesByIDs", err.Error()) + ctx.HTTPError(http.StatusInternalServerError, "FindIssuesByIDs", err.Error()) return } diff --git a/routers/web/repo/issue_new.go b/routers/web/repo/issue_new.go index 9115fc1771e1d..9f52396414f8b 100644 --- a/routers/web/repo/issue_new.go +++ b/routers/web/repo/issue_new.go @@ -255,7 +255,7 @@ func ValidateRepoMetasForNewIssue(ctx *context.Context, form forms.CreateIssueFo inputLabelIDs, _ := base.StringsToInt64s(strings.Split(form.LabelIDs, ",")) candidateLabels := toSet(pageMetaData.LabelsData.AllLabels, func(label *issues_model.Label) int64 { return label.ID }) if len(inputLabelIDs) > 0 && !candidateLabels.Contains(inputLabelIDs...) { - ctx.NotFound("", nil) + ctx.NotFound(nil) return ret } pageMetaData.LabelsData.SetSelectedLabelIDs(inputLabelIDs) @@ -263,7 +263,7 @@ func ValidateRepoMetasForNewIssue(ctx *context.Context, form forms.CreateIssueFo allMilestones := append(slices.Clone(pageMetaData.MilestonesData.OpenMilestones), pageMetaData.MilestonesData.ClosedMilestones...) candidateMilestones := toSet(allMilestones, func(milestone *issues_model.Milestone) int64 { return milestone.ID }) if form.MilestoneID > 0 && !candidateMilestones.Contains(form.MilestoneID) { - ctx.NotFound("", nil) + ctx.NotFound(nil) return ret } pageMetaData.MilestonesData.SelectedMilestoneID = form.MilestoneID @@ -271,7 +271,7 @@ func ValidateRepoMetasForNewIssue(ctx *context.Context, form forms.CreateIssueFo allProjects := append(slices.Clone(pageMetaData.ProjectsData.OpenProjects), pageMetaData.ProjectsData.ClosedProjects...) candidateProjects := toSet(allProjects, func(project *project_model.Project) int64 { return project.ID }) if form.ProjectID > 0 && !candidateProjects.Contains(form.ProjectID) { - ctx.NotFound("", nil) + ctx.NotFound(nil) return ret } pageMetaData.ProjectsData.SelectedProjectID = form.ProjectID @@ -304,14 +304,14 @@ func ValidateRepoMetasForNewIssue(ctx *context.Context, form forms.CreateIssueFo if rID < 0 { // negative reviewIDs represent team requests team, ok := teamReviewersMap[-rID] if !ok { - ctx.NotFound("", nil) + ctx.NotFound(nil) return ret } teamReviewers = append(teamReviewers, team) } else { user, ok := userReviewersMap[rID] if !ok { - ctx.NotFound("", nil) + ctx.NotFound(nil) return ret } reviewers = append(reviewers, user) @@ -349,7 +349,7 @@ func NewIssuePost(ctx *context.Context) { if projectID > 0 { if !ctx.Repo.CanRead(unit.TypeProjects) { // User must also be able to see the project. - ctx.Error(http.StatusBadRequest, "user hasn't permissions to read projects") + ctx.HTTPError(http.StatusBadRequest, "user hasn't permissions to read projects") return } } @@ -388,7 +388,7 @@ func NewIssuePost(ctx *context.Context) { if err := issue_service.NewIssue(ctx, repo, issue, labelIDs, attachments, assigneeIDs, projectID); err != nil { if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) { - ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) + ctx.HTTPError(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) } else if errors.Is(err, user_model.ErrBlockedUser) { ctx.JSONError(ctx.Tr("repo.issues.new.blocked_user")) } else { diff --git a/routers/web/repo/issue_pin.go b/routers/web/repo/issue_pin.go index d7d3205c378b6..8d3de90d25c43 100644 --- a/routers/web/repo/issue_pin.go +++ b/routers/web/repo/issue_pin.go @@ -6,6 +6,7 @@ package repo import ( "net/http" + "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" @@ -22,15 +23,29 @@ func IssuePinOrUnpin(ctx *context.Context) { // If we don't do this, it will crash when trying to add the pin event to the comment history err := issue.LoadRepo(ctx) if err != nil { - ctx.Status(http.StatusInternalServerError) - log.Error(err.Error()) + ctx.ServerError("LoadRepo", err) return } - err = issue.PinOrUnpin(ctx, ctx.Doer) + // PinOrUnpin pins or unpins a Issue + _, err = issues_model.GetIssuePin(ctx, issue) + if err != nil && !db.IsErrNotExist(err) { + ctx.ServerError("GetIssuePin", err) + return + } + + if db.IsErrNotExist(err) { + err = issues_model.PinIssue(ctx, issue, ctx.Doer) + } else { + err = issues_model.UnpinIssue(ctx, issue, ctx.Doer) + } + if err != nil { - ctx.Status(http.StatusInternalServerError) - log.Error(err.Error()) + if issues_model.IsErrIssueMaxPinReached(err) { + ctx.JSONError(ctx.Tr("repo.issues.max_pinned")) + } else { + ctx.ServerError("Pin/Unpin failed", err) + } return } @@ -41,23 +56,20 @@ func IssuePinOrUnpin(ctx *context.Context) { func IssueUnpin(ctx *context.Context) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { - ctx.Status(http.StatusInternalServerError) - log.Error(err.Error()) + ctx.ServerError("GetIssueByIndex", err) return } // If we don't do this, it will crash when trying to add the pin event to the comment history err = issue.LoadRepo(ctx) if err != nil { - ctx.Status(http.StatusInternalServerError) - log.Error(err.Error()) + ctx.ServerError("LoadRepo", err) return } - err = issue.Unpin(ctx, ctx.Doer) + err = issues_model.UnpinIssue(ctx, issue, ctx.Doer) if err != nil { - ctx.Status(http.StatusInternalServerError) - log.Error(err.Error()) + ctx.ServerError("UnpinIssue", err) return } @@ -78,15 +90,13 @@ func IssuePinMove(ctx *context.Context) { form := &movePinIssueForm{} if err := json.NewDecoder(ctx.Req.Body).Decode(&form); err != nil { - ctx.Status(http.StatusInternalServerError) - log.Error(err.Error()) + ctx.ServerError("Decode", err) return } issue, err := issues_model.GetIssueByID(ctx, form.ID) if err != nil { - ctx.Status(http.StatusInternalServerError) - log.Error(err.Error()) + ctx.ServerError("GetIssueByID", err) return } @@ -96,10 +106,9 @@ func IssuePinMove(ctx *context.Context) { return } - err = issue.MovePin(ctx, form.Position) + err = issues_model.MovePin(ctx, issue, form.Position) if err != nil { - ctx.Status(http.StatusInternalServerError) - log.Error(err.Error()) + ctx.ServerError("MovePin", err) return } diff --git a/routers/web/repo/issue_stopwatch.go b/routers/web/repo/issue_stopwatch.go index 5d6e723311ef6..73e279e0a6978 100644 --- a/routers/web/repo/issue_stopwatch.go +++ b/routers/web/repo/issue_stopwatch.go @@ -26,7 +26,7 @@ func IssueStopwatch(c *context.Context) { } if !c.Repo.CanUseTimetracker(c, issue, c.Doer) { - c.NotFound("CanUseTimetracker", nil) + c.NotFound(nil) return } @@ -49,7 +49,7 @@ func CancelStopwatch(c *context.Context) { return } if !c.Repo.CanUseTimetracker(c, issue, c.Doer) { - c.NotFound("CanUseTimetracker", nil) + c.NotFound(nil) return } diff --git a/routers/web/repo/issue_timetrack.go b/routers/web/repo/issue_timetrack.go index 134ded82d10ea..985bfd6698ff6 100644 --- a/routers/web/repo/issue_timetrack.go +++ b/routers/web/repo/issue_timetrack.go @@ -25,7 +25,7 @@ func AddTimeManually(c *context.Context) { return } if !c.Repo.CanUseTimetracker(c, issue, c.Doer) { - c.NotFound("CanUseTimetracker", nil) + c.NotFound(nil) return } @@ -56,23 +56,23 @@ func DeleteTime(c *context.Context) { return } if !c.Repo.CanUseTimetracker(c, issue, c.Doer) { - c.NotFound("CanUseTimetracker", nil) + c.NotFound(nil) return } t, err := issues_model.GetTrackedTimeByID(c, c.PathParamInt64("timeid")) if err != nil { if db.IsErrNotExist(err) { - c.NotFound("time not found", err) + c.NotFound(err) return } - c.Error(http.StatusInternalServerError, "GetTrackedTimeByID", err.Error()) + c.HTTPError(http.StatusInternalServerError, "GetTrackedTimeByID", err.Error()) return } // only OP or admin may delete if !c.IsSigned || (!c.IsUserSiteAdmin() && c.Doer.ID != t.UserID) { - c.Error(http.StatusForbidden, "not allowed") + c.HTTPError(http.StatusForbidden, "not allowed") return } @@ -92,7 +92,7 @@ func UpdateIssueTimeEstimate(ctx *context.Context) { } if !ctx.IsSigned || (!issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } diff --git a/routers/web/repo/issue_view.go b/routers/web/repo/issue_view.go index c8f3480ab81be..37e1b2793106e 100644 --- a/routers/web/repo/issue_view.go +++ b/routers/web/repo/issue_view.go @@ -297,7 +297,7 @@ func ViewIssue(ctx *context.Context) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound("GetIssueByIndex", err) + ctx.NotFound(err) } else { ctx.ServerError("GetIssueByIndex", err) } @@ -543,7 +543,11 @@ func preparePullViewDeleteBranch(ctx *context.Context, issue *issues_model.Issue func prepareIssueViewSidebarPin(ctx *context.Context, issue *issues_model.Issue) { var pinAllowed bool - if !issue.IsPinned() { + if err := issue.LoadPinOrder(ctx); err != nil { + ctx.ServerError("LoadPinOrder", err) + return + } + if issue.PinOrder == 0 { var err error pinAllowed, err = issues_model.IsNewPinAllowed(ctx, issue.RepoID, issue.IsPull) if err != nil { diff --git a/routers/web/repo/issue_watch.go b/routers/web/repo/issue_watch.go index e7d55e5555e95..dfa3491786ed7 100644 --- a/routers/web/repo/issue_watch.go +++ b/routers/web/repo/issue_watch.go @@ -42,7 +42,7 @@ func IssueWatch(ctx *context.Context) { log.Trace("Permission Denied: Not logged in") } } - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } diff --git a/routers/web/repo/migrate.go b/routers/web/repo/migrate.go index 3a7dc294667c9..ea15e90e5c297 100644 --- a/routers/web/repo/migrate.go +++ b/routers/web/repo/migrate.go @@ -35,7 +35,7 @@ const ( // Migrate render migration of repository page func Migrate(ctx *context.Context) { if setting.Repository.DisableMigrations { - ctx.Error(http.StatusForbidden, "Migrate: the site administrator has disabled migrations") + ctx.HTTPError(http.StatusForbidden, "Migrate: the site administrator has disabled migrations") return } @@ -72,7 +72,7 @@ func Migrate(ctx *context.Context) { func handleMigrateError(ctx *context.Context, owner *user_model.User, err error, name string, tpl templates.TplName, form *forms.MigrateRepoForm) { if setting.Repository.DisableMigrations { - ctx.Error(http.StatusForbidden, "MigrateError: the site administrator has disabled migrations") + ctx.HTTPError(http.StatusForbidden, "MigrateError: the site administrator has disabled migrations") return } @@ -152,12 +152,12 @@ func handleMigrateRemoteAddrError(ctx *context.Context, err error, tpl templates func MigratePost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.MigrateRepoForm) if setting.Repository.DisableMigrations { - ctx.Error(http.StatusForbidden, "MigratePost: the site administrator has disabled migrations") + ctx.HTTPError(http.StatusForbidden, "MigratePost: the site administrator has disabled migrations") return } if form.Mirror && setting.Mirror.DisableNewPull { - ctx.Error(http.StatusBadRequest, "MigratePost: the site administrator has disabled creation of new mirrors") + ctx.HTTPError(http.StatusBadRequest, "MigratePost: the site administrator has disabled creation of new mirrors") return } diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go index 6a0e6b25a9a63..f1d0a857eaa70 100644 --- a/routers/web/repo/milestone.go +++ b/routers/web/repo/milestone.go @@ -148,7 +148,7 @@ func EditMilestone(ctx *context.Context) { m, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrMilestoneNotExist(err) { - ctx.NotFound("", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetMilestoneByRepoID", err) } @@ -184,7 +184,7 @@ func EditMilestonePost(ctx *context.Context) { m, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("id")) if err != nil { if issues_model.IsErrMilestoneNotExist(err) { - ctx.NotFound("", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetMilestoneByRepoID", err) } @@ -218,7 +218,7 @@ func ChangeMilestoneStatus(ctx *context.Context) { if err := issues_model.ChangeMilestoneStatusByRepoIDAndID(ctx, ctx.Repo.Repository.ID, id, toClose); err != nil { if issues_model.IsErrMilestoneNotExist(err) { - ctx.NotFound("", err) + ctx.NotFound(err) } else { ctx.ServerError("ChangeMilestoneStatusByIDAndRepoID", err) } @@ -245,7 +245,7 @@ func MilestoneIssuesAndPulls(ctx *context.Context) { milestone, err := issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, milestoneID) if err != nil { if issues_model.IsErrMilestoneNotExist(err) { - ctx.NotFound("GetMilestoneByID", err) + ctx.NotFound(err) return } diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index 346132102f6c7..5b81a5e4d1b6e 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -39,14 +39,14 @@ const ( // MustEnableRepoProjects check if repo projects are enabled in settings func MustEnableRepoProjects(ctx *context.Context) { if unit.TypeProjects.UnitGlobalDisabled() { - ctx.NotFound("EnableRepoProjects", nil) + ctx.NotFound(nil) return } if ctx.Repo.Repository != nil { projectsUnit := ctx.Repo.Repository.MustGetUnit(ctx, unit.TypeProjects) if !ctx.Repo.CanRead(unit.TypeProjects) || !projectsUnit.ProjectsConfig().IsProjectsAllowed(repo_model.ProjectsModeRepo) { - ctx.NotFound("MustEnableRepoProjects", nil) + ctx.NotFound(nil) return } } @@ -92,6 +92,11 @@ func Projects(ctx *context.Context) { return } + if err := project_service.LoadIssueNumbersForProjects(ctx, projects, ctx.Doer); err != nil { + ctx.ServerError("LoadIssueNumbersForProjects", err) + return + } + for i := range projects { rctx := renderhelper.NewRenderContextRepoComment(ctx, repo) projects[i].RenderedContent, err = markdown.RenderString(rctx, projects[i].Description) @@ -189,14 +194,14 @@ func DeleteProject(ctx *context.Context) { p, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64("id")) if err != nil { if project_model.IsErrProjectNotExist(err) { - ctx.NotFound("", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetProjectByID", err) } return } if p.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -219,14 +224,14 @@ func RenderEditProject(ctx *context.Context) { p, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64("id")) if err != nil { if project_model.IsErrProjectNotExist(err) { - ctx.NotFound("", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetProjectByID", err) } return } if p.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -259,14 +264,14 @@ func EditProjectPost(ctx *context.Context) { p, err := project_model.GetProjectByID(ctx, projectID) if err != nil { if project_model.IsErrProjectNotExist(err) { - ctx.NotFound("", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetProjectByID", err) } return } if p.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -291,14 +296,14 @@ func ViewProject(ctx *context.Context) { project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64("id")) if err != nil { if project_model.IsErrProjectNotExist(err) { - ctx.NotFound("", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetProjectByID", err) } return } if project.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -312,7 +317,8 @@ func ViewProject(ctx *context.Context) { assigneeID := ctx.FormInt64("assignee") // TODO: use "optional" but not 0 in the future - issuesMap, err := issues_model.LoadIssuesFromColumnList(ctx, columns, &issues_model.IssuesOptions{ + issuesMap, err := project_service.LoadIssuesFromProject(ctx, project, &issues_model.IssuesOptions{ + RepoIDs: []int64{ctx.Repo.Repository.ID}, LabelIDs: labelIDs, AssigneeID: optional.Some(assigneeID), }) @@ -320,6 +326,9 @@ func ViewProject(ctx *context.Context) { ctx.ServerError("LoadIssuesOfColumns", err) return } + for _, column := range columns { + column.NumIssues = int64(len(issuesMap[column.ID])) + } if project.CardType != project_model.CardTypeTextOnly { issuesAttachmentMap := make(map[int64][]*repo_model.Attachment) @@ -471,7 +480,7 @@ func DeleteProjectColumn(ctx *context.Context) { project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64("id")) if err != nil { if project_model.IsErrProjectNotExist(err) { - ctx.NotFound("", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetProjectByID", err) } @@ -518,7 +527,7 @@ func AddColumnToProjectPost(ctx *context.Context) { project, err := project_model.GetProjectForRepoByID(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("id")) if err != nil { if project_model.IsErrProjectNotExist(err) { - ctx.NotFound("", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetProjectByID", err) } @@ -556,7 +565,7 @@ func checkProjectColumnChangePermissions(ctx *context.Context) (*project_model.P project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64("id")) if err != nil { if project_model.IsErrProjectNotExist(err) { - ctx.NotFound("", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetProjectByID", err) } @@ -642,21 +651,21 @@ func MoveIssues(ctx *context.Context) { project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64("id")) if err != nil { if project_model.IsErrProjectNotExist(err) { - ctx.NotFound("ProjectNotExist", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetProjectByID", err) } return } if project.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("InvalidRepoID", nil) + ctx.NotFound(nil) return } column, err := project_model.GetColumn(ctx, ctx.PathParamInt64("columnID")) if err != nil { if project_model.IsErrProjectColumnNotExist(err) { - ctx.NotFound("ProjectColumnNotExist", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetProjectColumn", err) } @@ -664,7 +673,7 @@ func MoveIssues(ctx *context.Context) { } if column.ProjectID != project.ID { - ctx.NotFound("ColumnNotInProject", nil) + ctx.NotFound(nil) return } @@ -689,7 +698,7 @@ func MoveIssues(ctx *context.Context) { movedIssues, err := issues_model.GetIssuesByIDs(ctx, issueIDs) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound("IssueNotExisting", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetIssueByID", err) } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 43524daeb4c6d..223f8d017ed30 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -81,7 +81,7 @@ func getRepository(ctx *context.Context, repoID int64) *repo_model.Repository { repo, err := repo_model.GetRepositoryByID(ctx, repoID) if err != nil { if repo_model.IsErrRepoNotExist(err) { - ctx.NotFound("GetRepositoryByID", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetRepositoryByID", err) } @@ -101,7 +101,7 @@ func getRepository(ctx *context.Context, repoID int64) *repo_model.Repository { unit.TypeCode, ctx.Repo, perm) - ctx.NotFound("getRepository", nil) + ctx.NotFound(nil) return nil } return repo @@ -111,7 +111,7 @@ func getPullInfo(ctx *context.Context) (issue *issues_model.Issue, ok bool) { issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound("GetIssueByIndex", err) + ctx.NotFound(err) } else { ctx.ServerError("GetIssueByIndex", err) } @@ -129,7 +129,7 @@ func getPullInfo(ctx *context.Context) (issue *issues_model.Issue, ok bool) { ctx.Data["Issue"] = issue if !issue.IsPull { - ctx.NotFound("ViewPullCommits", nil) + ctx.NotFound(nil) return nil, false } @@ -190,7 +190,7 @@ func GetPullDiffStats(ctx *context.Context) { mergeBaseCommitID := GetMergedBaseCommitID(ctx, issue) if mergeBaseCommitID == "" { - ctx.NotFound("PullFiles", nil) + ctx.NotFound(nil) return } @@ -624,7 +624,7 @@ func ViewPullCommits(ctx *context.Context) { if ctx.Written() { return } else if prInfo == nil { - ctx.NotFound("ViewPullCommits", nil) + ctx.NotFound(nil) return } @@ -672,7 +672,7 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi if ctx.Written() { return } else if prInfo == nil { - ctx.NotFound("ViewPullFiles", nil) + ctx.NotFound(nil) return } @@ -697,7 +697,7 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi } if !(foundStartCommit && foundEndCommit) { - ctx.NotFound("Given SHA1 not found for this PR", nil) + ctx.NotFound(nil) return } } @@ -935,11 +935,11 @@ func UpdatePullRequest(ctx *context.Context) { return } if issue.IsClosed { - ctx.NotFound("MergePullRequest", nil) + ctx.NotFound(nil) return } if issue.PullRequest.HasMerged { - ctx.NotFound("MergePullRequest", nil) + ctx.NotFound(nil) return } @@ -1338,7 +1338,7 @@ func CompareAndPullRequestPost(ctx *context.Context) { if err := pull_service.NewPullRequest(ctx, prOpts); err != nil { switch { case repo_model.IsErrUserDoesNotHaveAccessToRepo(err): - ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) + ctx.HTTPError(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error()) case git.IsErrPushRejected(err): pushrejErr := err.(*git.ErrPushRejected) message := pushrejErr.Message @@ -1409,7 +1409,7 @@ func CleanUpPullRequest(ctx *context.Context) { // Don't cleanup unmerged and unclosed PRs and agit PRs if !pr.HasMerged && !issue.IsClosed && pr.Flow != issues_model.PullRequestFlowGithub { - ctx.NotFound("CleanUpPullRequest", nil) + ctx.NotFound(nil) return } @@ -1420,7 +1420,7 @@ func CleanUpPullRequest(ctx *context.Context) { return } if exist { - ctx.NotFound("CleanUpPullRequest", nil) + ctx.NotFound(nil) return } @@ -1429,7 +1429,7 @@ func CleanUpPullRequest(ctx *context.Context) { return } else if pr.HeadRepo == nil { // Forked repository has already been deleted - ctx.NotFound("CleanUpPullRequest", nil) + ctx.NotFound(nil) return } else if err = pr.LoadBaseRepo(ctx); err != nil { ctx.ServerError("LoadBaseRepo", err) @@ -1441,7 +1441,7 @@ func CleanUpPullRequest(ctx *context.Context) { if err := repo_service.CanDeleteBranch(ctx, pr.HeadRepo, pr.HeadBranch, ctx.Doer); err != nil { if errors.Is(err, util.ErrPermissionDenied) { - ctx.NotFound("CanDeleteBranch", nil) + ctx.NotFound(nil) } else { ctx.ServerError("CanDeleteBranch", err) } @@ -1541,7 +1541,7 @@ func DownloadPullDiffOrPatch(ctx *context.Context, patch bool) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound("GetPullRequestByIndex", err) + ctx.NotFound(err) } else { ctx.ServerError("GetPullRequestByIndex", err) } @@ -1564,18 +1564,18 @@ func UpdatePullRequestTarget(ctx *context.Context) { } pr := issue.PullRequest if !issue.IsPull { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if !ctx.IsSigned || (!issue.IsPoster(ctx.Doer.ID) && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)) { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } targetBranch := ctx.FormTrim("target_branch") if len(targetBranch) == 0 { - ctx.Error(http.StatusNoContent) + ctx.HTTPError(http.StatusNoContent) return } @@ -1634,7 +1634,7 @@ func SetAllowEdits(ctx *context.Context) { pr, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) if err != nil { if issues_model.IsErrPullRequestNotExist(err) { - ctx.NotFound("GetPullRequestByIndex", err) + ctx.NotFound(err) } else { ctx.ServerError("GetPullRequestByIndex", err) } @@ -1643,7 +1643,7 @@ func SetAllowEdits(ctx *context.Context) { if err := pull_service.SetAllowEdits(ctx, ctx.Doer, pr, form.AllowMaintainerEdit); err != nil { if errors.Is(err, pull_service.ErrUserHasNoPermissionForAction) { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } ctx.ServerError("SetAllowEdits", err) diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go index 3e9e615b15dab..fb92d24394c0d 100644 --- a/routers/web/repo/pull_review.go +++ b/routers/web/repo/pull_review.go @@ -133,7 +133,7 @@ func UpdateResolveConversation(ctx *context.Context) { } if comment.Issue.RepoID != ctx.Repo.Repository.ID { - ctx.NotFound("comment's repoID is incorrect", errors.New("comment's repoID is incorrect")) + ctx.NotFound(errors.New("comment's repoID is incorrect")) return } @@ -143,12 +143,12 @@ func UpdateResolveConversation(ctx *context.Context) { return } if !permResult { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } if !comment.Issue.IsPull { - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } @@ -159,7 +159,7 @@ func UpdateResolveConversation(ctx *context.Context) { return } } else { - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } @@ -214,7 +214,7 @@ func renderConversation(ctx *context.Context, comment *issues_model.Comment, ori } else if origin == "timeline" { ctx.HTML(http.StatusOK, tplTimelineConversation) } else { - ctx.Error(http.StatusBadRequest, "Unknown origin: "+origin) + ctx.HTTPError(http.StatusBadRequest, "Unknown origin: "+origin) } } diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index 284fd27abf72b..2ad0bf7e3a98a 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -285,7 +285,7 @@ func SingleRelease(ctx *context.Context) { return } if len(releases) != 1 { - ctx.NotFound("SingleRelease", err) + ctx.NotFound(err) return } @@ -311,7 +311,7 @@ func LatestRelease(ctx *context.Context) { release, err := repo_model.GetLatestReleaseByRepoID(ctx, ctx.Repo.Repository.ID) if err != nil { if repo_model.IsErrReleaseNotExist(err) { - ctx.NotFound("LatestRelease", err) + ctx.NotFound(err) return } ctx.ServerError("GetLatestReleaseByRepoID", err) @@ -525,7 +525,7 @@ func EditRelease(ctx *context.Context) { rel, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, tagName) if err != nil { if repo_model.IsErrReleaseNotExist(err) { - ctx.NotFound("GetRelease", err) + ctx.NotFound(err) } else { ctx.ServerError("GetRelease", err) } @@ -568,14 +568,14 @@ func EditReleasePost(ctx *context.Context) { rel, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, tagName) if err != nil { if repo_model.IsErrReleaseNotExist(err) { - ctx.NotFound("GetRelease", err) + ctx.NotFound(err) } else { ctx.ServerError("GetRelease", err) } return } if rel.IsTag { - ctx.NotFound("GetRelease", err) + ctx.NotFound(err) return } ctx.Data["tag_name"] = rel.TagName @@ -639,7 +639,7 @@ func deleteReleaseOrTag(ctx *context.Context, isDelTag bool) { rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, ctx.FormInt64("id")) if err != nil { if repo_model.IsErrReleaseNotExist(err) { - ctx.NotFound("GetReleaseForRepoByID", err) + ctx.NotFound(err) } else { ctx.Flash.Error("DeleteReleaseByID: " + err.Error()) redirect() diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go index efd271c01d638..689174dfa1aa5 100644 --- a/routers/web/repo/render.go +++ b/routers/web/repo/render.go @@ -30,7 +30,7 @@ func RenderFile(ctx *context.Context) { } if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("GetBlobByPath", err) + ctx.NotFound(err) } else { ctx.ServerError("GetBlobByPath", err) } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 0d4513ec67b26..73baf683ed577 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -45,14 +45,14 @@ const ( // MustBeNotEmpty render when a repo is a empty git dir func MustBeNotEmpty(ctx *context.Context) { if ctx.Repo.Repository.IsEmpty { - ctx.NotFound("MustBeNotEmpty", nil) + ctx.NotFound(nil) } } // MustBeEditable check that repo can be edited func MustBeEditable(ctx *context.Context) { if !ctx.Repo.Repository.CanEnableEditor() { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } } @@ -60,7 +60,7 @@ func MustBeEditable(ctx *context.Context) { // MustBeAbleToUpload check that repo can be uploaded to func MustBeAbleToUpload(ctx *context.Context) { if !setting.Repository.Upload.Enabled { - ctx.NotFound("", nil) + ctx.NotFound(nil) } } @@ -116,7 +116,7 @@ func checkContextUser(ctx *context.Context, uid int64) *user_model.User { // Check ownership of organization. if !org.IsOrganization() { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return nil } if !ctx.Doer.IsAdmin { @@ -125,7 +125,7 @@ func checkContextUser(ctx *context.Context, uid int64) *user_model.User { ctx.ServerError("CanCreateOrgRepo", err) return nil } else if !canCreate { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return nil } } else { @@ -308,7 +308,7 @@ func handleActionError(ctx *context.Context, err error) { if errors.Is(err, user_model.ErrBlockedUser) { ctx.Flash.Error(ctx.Tr("repo.action.blocked_user")) } else if errors.Is(err, util.ErrPermissionDenied) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) } else { ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.PathParam("action")), err) } @@ -335,7 +335,7 @@ func RedirectDownload(ctx *context.Context) { release := releases[0] att, err := repo_model.GetAttachmentByReleaseIDFileName(ctx, release.ID, fileName) if err != nil { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if att != nil { @@ -347,12 +347,12 @@ func RedirectDownload(ctx *context.Context) { // We only fetch the latest release if the tag is "latest" and no release with the tag "latest" exists release, err := repo_model.GetLatestReleaseByRepoID(ctx, ctx.Repo.Repository.ID) if err != nil { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } att, err := repo_model.GetAttachmentByReleaseIDFileName(ctx, release.ID, fileName) if err != nil { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if att != nil { @@ -360,7 +360,7 @@ func RedirectDownload(ctx *context.Context) { return } } - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) } // Download an archive of a repository @@ -368,9 +368,9 @@ func Download(ctx *context.Context) { aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*")) if err != nil { if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) { - ctx.Error(http.StatusBadRequest, err.Error()) + ctx.HTTPError(http.StatusBadRequest, err.Error()) } else if errors.Is(err, archiver_service.RepoRefNotFoundError{}) { - ctx.Error(http.StatusNotFound, err.Error()) + ctx.HTTPError(http.StatusNotFound, err.Error()) } else { ctx.ServerError("archiver_service.NewRequest", err) } @@ -425,11 +425,11 @@ func download(ctx *context.Context, archiveName string, archiver *repo_model.Rep func InitiateDownload(ctx *context.Context) { aReq, err := archiver_service.NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.PathParam("*")) if err != nil { - ctx.Error(http.StatusBadRequest, "invalid archive request") + ctx.HTTPError(http.StatusBadRequest, "invalid archive request") return } if aReq == nil { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -501,7 +501,7 @@ func SearchRepo(ctx *context.Context) { opts.Collaborate = optional.Some(true) case "": default: - ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid search mode: \"%s\"", mode)) + ctx.HTTPError(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid search mode: \"%s\"", mode)) return } @@ -523,11 +523,11 @@ func SearchRepo(ctx *context.Context) { if orderBy, ok := searchModeMap[sortMode]; ok { opts.OrderBy = orderBy } else { - ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid sort mode: \"%s\"", sortMode)) + ctx.HTTPError(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid sort mode: \"%s\"", sortMode)) return } } else { - ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid sort order: \"%s\"", sortOrder)) + ctx.HTTPError(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid sort order: \"%s\"", sortOrder)) return } } diff --git a/routers/web/repo/setting/default_branch.go b/routers/web/repo/setting/default_branch.go index 881d148afc45c..e0822ba54057b 100644 --- a/routers/web/repo/setting/default_branch.go +++ b/routers/web/repo/setting/default_branch.go @@ -49,6 +49,6 @@ func SetDefaultBranchPost(ctx *context.Context) { ctx.Flash.Success(ctx.Tr("repo.settings.update_settings_success")) ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath()) default: - ctx.NotFound("", nil) + ctx.NotFound(nil) } } diff --git a/routers/web/repo/setting/git_hooks.go b/routers/web/repo/setting/git_hooks.go index 1d9221130398c..ba4b5e85b63a1 100644 --- a/routers/web/repo/setting/git_hooks.go +++ b/routers/web/repo/setting/git_hooks.go @@ -34,7 +34,7 @@ func GitHooksEdit(ctx *context.Context) { hook, err := ctx.Repo.GitRepo.GetHook(name) if err != nil { if err == git.ErrNotValidHook { - ctx.NotFound("GetHook", err) + ctx.NotFound(err) } else { ctx.ServerError("GetHook", err) } @@ -50,7 +50,7 @@ func GitHooksEditPost(ctx *context.Context) { hook, err := ctx.Repo.GitRepo.GetHook(name) if err != nil { if err == git.ErrNotValidHook { - ctx.NotFound("GetHook", err) + ctx.NotFound(err) } else { ctx.ServerError("GetHook", err) } diff --git a/routers/web/repo/setting/lfs.go b/routers/web/repo/setting/lfs.go index 2df483fa3453d..655291d25c3a4 100644 --- a/routers/web/repo/setting/lfs.go +++ b/routers/web/repo/setting/lfs.go @@ -41,7 +41,7 @@ const ( // LFSFiles shows a repository's LFS files func LFSFiles(ctx *context.Context) { if !setting.LFS.StartServer { - ctx.NotFound("LFSFiles", nil) + ctx.NotFound(nil) return } page := ctx.FormInt("page") @@ -71,7 +71,7 @@ func LFSFiles(ctx *context.Context) { // LFSLocks shows a repository's LFS locks func LFSLocks(ctx *context.Context) { if !setting.LFS.StartServer { - ctx.NotFound("LFSLocks", nil) + ctx.NotFound(nil) return } ctx.Data["LFSFilesLink"] = ctx.Repo.RepoLink + "/settings/lfs" @@ -197,7 +197,7 @@ func LFSLocks(ctx *context.Context) { // LFSLockFile locks a file func LFSLockFile(ctx *context.Context) { if !setting.LFS.StartServer { - ctx.NotFound("LFSLocks", nil) + ctx.NotFound(nil) return } originalPath := ctx.FormString("path") @@ -238,7 +238,7 @@ func LFSLockFile(ctx *context.Context) { // LFSUnlock forcibly unlocks an LFS lock func LFSUnlock(ctx *context.Context) { if !setting.LFS.StartServer { - ctx.NotFound("LFSUnlock", nil) + ctx.NotFound(nil) return } _, err := git_model.DeleteLFSLockByID(ctx, ctx.PathParamInt64("lid"), ctx.Repo.Repository, ctx.Doer, true) @@ -252,7 +252,7 @@ func LFSUnlock(ctx *context.Context) { // LFSFileGet serves a single LFS file func LFSFileGet(ctx *context.Context) { if !setting.LFS.StartServer { - ctx.NotFound("LFSFileGet", nil) + ctx.NotFound(nil) return } ctx.Data["LFSFilesLink"] = ctx.Repo.RepoLink + "/settings/lfs" @@ -260,7 +260,7 @@ func LFSFileGet(ctx *context.Context) { p := lfs.Pointer{Oid: oid} if !p.IsValid() { - ctx.NotFound("LFSFileGet", nil) + ctx.NotFound(nil) return } @@ -269,7 +269,7 @@ func LFSFileGet(ctx *context.Context) { meta, err := git_model.GetLFSMetaObjectByOid(ctx, ctx.Repo.Repository.ID, oid) if err != nil { if err == git_model.ErrLFSObjectNotExist { - ctx.NotFound("LFSFileGet", nil) + ctx.NotFound(nil) return } ctx.ServerError("LFSFileGet", err) @@ -350,13 +350,13 @@ func LFSFileGet(ctx *context.Context) { // LFSDelete disassociates the provided oid from the repository and if the lfs file is no longer associated with any repositories - deletes it func LFSDelete(ctx *context.Context) { if !setting.LFS.StartServer { - ctx.NotFound("LFSDelete", nil) + ctx.NotFound(nil) return } oid := ctx.PathParam("oid") p := lfs.Pointer{Oid: oid} if !p.IsValid() { - ctx.NotFound("LFSDelete", nil) + ctx.NotFound(nil) return } @@ -381,13 +381,13 @@ func LFSDelete(ctx *context.Context) { // LFSFileFind guesses a sha for the provided oid (or uses the provided sha) and then finds the commits that contain this sha func LFSFileFind(ctx *context.Context) { if !setting.LFS.StartServer { - ctx.NotFound("LFSFind", nil) + ctx.NotFound(nil) return } oid := ctx.FormString("oid") size := ctx.FormInt64("size") if len(oid) == 0 || size == 0 { - ctx.NotFound("LFSFind", nil) + ctx.NotFound(nil) return } sha := ctx.FormString("sha") @@ -421,7 +421,7 @@ func LFSFileFind(ctx *context.Context) { // LFSPointerFiles will search the repository for pointer files and report which are missing LFS files in the content store func LFSPointerFiles(ctx *context.Context) { if !setting.LFS.StartServer { - ctx.NotFound("LFSFileGet", nil) + ctx.NotFound(nil) return } ctx.Data["PageIsSettingsLFS"] = true @@ -532,7 +532,7 @@ func LFSPointerFiles(ctx *context.Context) { // LFSAutoAssociate auto associates accessible lfs files func LFSAutoAssociate(ctx *context.Context) { if !setting.LFS.StartServer { - ctx.NotFound("LFSAutoAssociate", nil) + ctx.NotFound(nil) return } oids := ctx.FormStrings("oid") diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go index 06a9e69507193..6709bd115caee 100644 --- a/routers/web/repo/setting/protected_branch.go +++ b/routers/web/repo/setting/protected_branch.go @@ -340,7 +340,7 @@ func RenameBranchPost(ctx *context.Context) { form := web.GetForm(ctx).(*forms.RenameBranchForm) if !ctx.Repo.CanCreateBranch() { - ctx.NotFound("RenameBranch", nil) + ctx.NotFound(nil) return } diff --git a/routers/web/repo/setting/protected_tag.go b/routers/web/repo/setting/protected_tag.go index 1730ad4a8bec8..33692778d5376 100644 --- a/routers/web/repo/setting/protected_tag.go +++ b/routers/web/repo/setting/protected_tag.go @@ -183,7 +183,7 @@ func selectProtectedTagByContext(ctx *context.Context) *git_model.ProtectedTag { return tag } - ctx.NotFound("", fmt.Errorf("ProtectedTag[%v] not associated to repository %v", id, ctx.Repo.Repository)) + ctx.NotFound(fmt.Errorf("ProtectedTag[%v] not associated to repository %v", id, ctx.Repo.Repository)) return nil } diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index be37d0a9c450e..768484a21c2a7 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -189,13 +189,13 @@ func SettingsPost(ctx *context.Context) { case "mirror": if !setting.Mirror.Enabled || !repo.IsMirror || repo.IsArchived { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } pullMirror, err := repo_model.GetMirrorByRepoID(ctx, ctx.Repo.Repository.ID) if err == repo_model.ErrMirrorNotExist { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } if err != nil { @@ -283,7 +283,7 @@ func SettingsPost(ctx *context.Context) { case "mirror-sync": if !setting.Mirror.Enabled || !repo.IsMirror || repo.IsArchived { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -294,13 +294,13 @@ func SettingsPost(ctx *context.Context) { case "push-mirror-sync": if !setting.Mirror.Enabled { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } m, _, _ := repo_model.GetPushMirrorByIDAndRepoID(ctx, form.PushMirrorID, repo.ID) if m == nil { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -311,7 +311,7 @@ func SettingsPost(ctx *context.Context) { case "push-mirror-update": if !setting.Mirror.Enabled || repo.IsArchived { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -327,7 +327,7 @@ func SettingsPost(ctx *context.Context) { m, _, _ := repo_model.GetPushMirrorByIDAndRepoID(ctx, form.PushMirrorID, repo.ID) if m == nil { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -349,7 +349,7 @@ func SettingsPost(ctx *context.Context) { case "push-mirror-remove": if !setting.Mirror.Enabled || repo.IsArchived { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -359,7 +359,7 @@ func SettingsPost(ctx *context.Context) { m, _, _ := repo_model.GetPushMirrorByIDAndRepoID(ctx, form.PushMirrorID, repo.ID) if m == nil { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -378,7 +378,7 @@ func SettingsPost(ctx *context.Context) { case "push-mirror-add": if setting.Mirror.DisableNewPush || repo.IsArchived { - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -650,7 +650,7 @@ func SettingsPost(ctx *context.Context) { case "admin": if !ctx.Doer.IsAdmin { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -670,7 +670,7 @@ func SettingsPost(ctx *context.Context) { case "admin_index": if !ctx.Doer.IsAdmin { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -682,12 +682,12 @@ func SettingsPost(ctx *context.Context) { } case "code": if !setting.Indexer.RepoIndexerEnabled { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } code.UpdateRepoIndexer(ctx.Repo.Repository) default: - ctx.NotFound("", nil) + ctx.NotFound(nil) return } @@ -698,7 +698,7 @@ func SettingsPost(ctx *context.Context) { case "convert": if !ctx.Repo.IsOwner() { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if repo.Name != form.RepoName { @@ -707,7 +707,7 @@ func SettingsPost(ctx *context.Context) { } if !repo.IsMirror { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } repo.IsMirror = false @@ -725,7 +725,7 @@ func SettingsPost(ctx *context.Context) { case "convert_fork": if !ctx.Repo.IsOwner() { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if err := repo.LoadOwner(ctx); err != nil { @@ -738,7 +738,7 @@ func SettingsPost(ctx *context.Context) { } if !repo.IsFork { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -762,7 +762,7 @@ func SettingsPost(ctx *context.Context) { case "transfer": if !ctx.Repo.IsOwner() { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if repo.Name != form.RepoName { @@ -820,7 +820,7 @@ func SettingsPost(ctx *context.Context) { case "cancel_transfer": if !ctx.Repo.IsOwner() { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -846,7 +846,7 @@ func SettingsPost(ctx *context.Context) { case "delete": if !ctx.Repo.IsOwner() { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if repo.Name != form.RepoName { @@ -870,7 +870,7 @@ func SettingsPost(ctx *context.Context) { case "delete-wiki": if !ctx.Repo.IsOwner() { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if repo.Name != form.RepoName { @@ -889,7 +889,7 @@ func SettingsPost(ctx *context.Context) { case "archive": if !ctx.Repo.IsOwner() { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -920,7 +920,7 @@ func SettingsPost(ctx *context.Context) { case "unarchive": if !ctx.Repo.IsOwner() { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -979,7 +979,7 @@ func SettingsPost(ctx *context.Context) { ctx.Redirect(ctx.Repo.RepoLink + "/settings") default: - ctx.NotFound("", nil) + ctx.NotFound(nil) } } diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index b15f97d6907dd..395ba94e1a25c 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -112,7 +112,7 @@ func getOwnerRepoCtx(ctx *context.Context) (*ownerRepoCtx, error) { func checkHookType(ctx *context.Context) string { hookType := strings.ToLower(ctx.PathParam("type")) if !util.SliceContainsString(setting.Webhook.Types, hookType, true) { - ctx.NotFound("checkHookType", nil) + ctx.NotFound(nil) return "" } return hookType @@ -602,7 +602,7 @@ func checkWebhook(ctx *context.Context) (*ownerRepoCtx, *webhook.Webhook) { } if err != nil || w == nil { if webhook.IsErrWebhookNotExist(err) { - ctx.NotFound("GetWebhookByID", nil) + ctx.NotFound(nil) } else { ctx.ServerError("GetWebhookByID", err) } @@ -719,7 +719,7 @@ func ReplayWebhook(ctx *context.Context) { if err := webhook_service.ReplayHookTask(ctx, w, hookTaskUUID); err != nil { if webhook.IsErrHookTaskNotExist(err) { - ctx.NotFound("ReplayHookTask", nil) + ctx.NotFound(nil) } else { ctx.ServerError("ReplayHookTask", err) } diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index df3228a90262b..cb9c278cac08e 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -216,7 +216,7 @@ func checkHomeCodeViewable(ctx *context.Context) { } } - ctx.NotFound("Home", errors.New(ctx.Locale.TrString("units.error.no_unit_allowed_repo"))) + ctx.NotFound(errors.New(ctx.Locale.TrString("units.error.no_unit_allowed_repo"))) } // LastCommit returns lastCommit data for the provided branch/tag/commit and directory (in url) and filenames in body diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 29b3c78a754f8..98c84b6993154 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -58,7 +58,7 @@ func MustEnableWiki(ctx *context.Context) { ctx.Repo.Repository, ctx.Repo.Permission) } - ctx.NotFound("MustEnableWiki", nil) + ctx.NotFound(nil) return } @@ -485,7 +485,7 @@ func renderEditPage(ctx *context.Context) { ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages") } if isRaw { - ctx.Error(http.StatusForbidden, "Editing of raw wiki files is not allowed") + ctx.HTTPError(http.StatusForbidden, "Editing of raw wiki files is not allowed") } if entry == nil || ctx.Written() { return @@ -509,14 +509,14 @@ func WikiPost(ctx *context.Context) { switch ctx.FormString("action") { case "_new": if !ctx.Repo.CanWrite(unit.TypeWiki) { - ctx.NotFound(ctx.Req.URL.RequestURI(), nil) + ctx.NotFound(nil) return } NewWikiPost(ctx) return case "_delete": if !ctx.Repo.CanWrite(unit.TypeWiki) { - ctx.NotFound(ctx.Req.URL.RequestURI(), nil) + ctx.NotFound(nil) return } DeleteWikiPagePost(ctx) @@ -524,7 +524,7 @@ func WikiPost(ctx *context.Context) { } if !ctx.Repo.CanWrite(unit.TypeWiki) { - ctx.NotFound(ctx.Req.URL.RequestURI(), nil) + ctx.NotFound(nil) return } EditWikiPost(ctx) @@ -543,14 +543,14 @@ func Wiki(ctx *context.Context) { return case "_edit": if !ctx.Repo.CanWrite(unit.TypeWiki) { - ctx.NotFound(ctx.Req.URL.RequestURI(), nil) + ctx.NotFound(nil) return } EditWiki(ctx) return case "_new": if !ctx.Repo.CanWrite(unit.TypeWiki) { - ctx.NotFound(ctx.Req.URL.RequestURI(), nil) + ctx.NotFound(nil) return } NewWiki(ctx) @@ -710,7 +710,7 @@ func WikiRaw(ctx *context.Context) { if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("findEntryForFile", nil) + ctx.NotFound(nil) return } ctx.ServerError("findEntryForfile", err) @@ -746,7 +746,7 @@ func WikiRaw(ctx *context.Context) { return } - ctx.NotFound("findEntryForFile", nil) + ctx.NotFound(nil) } // NewWiki render wiki create page diff --git a/routers/web/shared/actions/runners.go b/routers/web/shared/actions/runners.go index 41aac4976bee2..444bd960db58d 100644 --- a/routers/web/shared/actions/runners.go +++ b/routers/web/shared/actions/runners.go @@ -200,7 +200,7 @@ func RunnersEdit(ctx *context.Context) { } if !runner.Editable(ownerID, repoID) { err = errors.New("no permission to edit this runner") - ctx.NotFound("RunnerDetails", err) + ctx.NotFound(err) return } @@ -252,7 +252,7 @@ func RunnersEditPost(ctx *context.Context) { return } if !runner.Editable(ownerID, repoID) { - ctx.NotFound("RunnerDetailsEditPost.Editable", util.NewPermissionDeniedErrorf("no permission to edit this runner")) + ctx.NotFound(util.NewPermissionDeniedErrorf("no permission to edit this runner")) return } @@ -306,7 +306,7 @@ func RunnerDeletePost(ctx *context.Context) { } if !runner.Editable(rCtx.OwnerID, rCtx.RepoID) { - ctx.NotFound("RunnerDeletePost", util.NewPermissionDeniedErrorf("no permission to delete this runner")) + ctx.NotFound(util.NewPermissionDeniedErrorf("no permission to delete this runner")) return } @@ -359,7 +359,7 @@ func findActionsRunner(ctx *context.Context, rCtx *runnersCtx) *actions_model.Ac ctx.ServerError("FindRunner", err) return nil } else if len(got) == 0 { - ctx.NotFound("FindRunner", errors.New("runner not found")) + ctx.NotFound(errors.New("runner not found")) return nil } diff --git a/routers/web/shared/actions/variables.go b/routers/web/shared/actions/variables.go index 052a8fdd1835b..7e8100b9485c0 100644 --- a/routers/web/shared/actions/variables.go +++ b/routers/web/shared/actions/variables.go @@ -193,7 +193,7 @@ func findActionsVariable(ctx *context.Context, id int64, vCtx *variablesCtx) *ac ctx.ServerError("FindVariables", err) return nil } else if len(got) == 0 { - ctx.NotFound("FindVariables", nil) + ctx.NotFound(nil) return nil } return got[0] diff --git a/routers/web/shared/packages/packages.go b/routers/web/shared/packages/packages.go index a1bcb09850698..3d1795b42c041 100644 --- a/routers/web/shared/packages/packages.go +++ b/routers/web/shared/packages/packages.go @@ -210,7 +210,7 @@ func getCleanupRuleByContext(ctx *context.Context, owner *user_model.User) *pack pcr, err := packages_model.GetCleanupRuleByID(ctx, id) if err != nil { if err == packages_model.ErrPackageCleanupRuleNotExist { - ctx.NotFound("", err) + ctx.NotFound(err) } else { ctx.ServerError("GetCleanupRuleByID", err) } @@ -221,7 +221,7 @@ func getCleanupRuleByContext(ctx *context.Context, owner *user_model.User) *pack return pcr } - ctx.NotFound("", fmt.Errorf("PackageCleanupRule[%v] not associated to owner %v", id, owner)) + ctx.NotFound(fmt.Errorf("PackageCleanupRule[%v] not associated to owner %v", id, owner)) return nil } diff --git a/routers/web/shared/project/column.go b/routers/web/shared/project/column.go index 141c80716f541..b6ffaea7f8aca 100644 --- a/routers/web/shared/project/column.go +++ b/routers/web/shared/project/column.go @@ -17,7 +17,7 @@ func MoveColumns(ctx *context.Context) { return } if !project.CanBeAccessedByOwnerRepo(ctx.ContextUser.ID, ctx.Repo.Repository) { - ctx.NotFound("CanBeAccessedByOwnerRepo", nil) + ctx.NotFound(nil) return } diff --git a/routers/web/user/home.go b/routers/web/user/home.go index ff9334da6e2fa..dc78950cf2ecb 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -417,7 +417,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { IsPull: optional.Some(isPullList), SortType: sortType, IsArchived: optional.Some(false), - User: ctx.Doer, + Doer: ctx.Doer, } // -------------------------------------------------------------------------- // Build opts (IssuesOptions), which contains filter information. @@ -429,7 +429,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { // Get repository IDs where User/Org/Team has access. if ctx.Org != nil && ctx.Org.Organization != nil { - opts.Org = ctx.Org.Organization + opts.Owner = ctx.Org.Organization.AsUser() opts.Team = ctx.Org.Team issue.PrepareFilterIssueLabels(ctx, 0, ctx.Org.Organization.AsUser()) @@ -724,7 +724,7 @@ func UsernameSubRoute(ctx *context.Context) { // check view permissions if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) { - ctx.NotFound("user", fmt.Errorf("%s", ctx.ContextUser.Name)) + ctx.NotFound(fmt.Errorf("%s", ctx.ContextUser.Name)) return false } return true @@ -744,7 +744,7 @@ func UsernameSubRoute(ctx *context.Context) { } case strings.HasSuffix(username, ".rss"): if !setting.Other.EnableFeed { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if reloadParam(".rss") { @@ -752,7 +752,7 @@ func UsernameSubRoute(ctx *context.Context) { } case strings.HasSuffix(username, ".atom"): if !setting.Other.EnableFeed { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } if reloadParam(".atom") { diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 1f75faf1c644f..c01bc96e2bfe6 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -139,7 +139,7 @@ func RedirectToLastVersion(ctx *context.Context) { p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.PathParam("type")), ctx.PathParam("name")) if err != nil { if err == packages_model.ErrPackageNotExist { - ctx.NotFound("GetPackageByName", err) + ctx.NotFound(err) } else { ctx.ServerError("GetPackageByName", err) } @@ -155,7 +155,7 @@ func RedirectToLastVersion(ctx *context.Context) { return } if len(pvs) == 0 { - ctx.NotFound("", err) + ctx.NotFound(err) return } @@ -317,7 +317,7 @@ func ListPackageVersions(ctx *context.Context) { p, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.Type(ctx.PathParam("type")), ctx.PathParam("name")) if err != nil { if err == packages_model.ErrPackageNotExist { - ctx.NotFound("GetPackageByName", err) + ctx.NotFound(err) } else { ctx.ServerError("GetPackageByName", err) } @@ -496,7 +496,7 @@ func DownloadPackageFile(ctx *context.Context) { pf, err := packages_model.GetFileForVersionByID(ctx, ctx.Package.Descriptor.Version.ID, ctx.PathParamInt64("fileid")) if err != nil { if err == packages_model.ErrPackageFileNotExist { - ctx.NotFound("", err) + ctx.NotFound(err) } else { ctx.ServerError("GetFileForVersionByID", err) } diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go index 7cda3c038cf4c..39f066a53c904 100644 --- a/routers/web/user/profile.go +++ b/routers/web/user/profile.go @@ -56,7 +56,7 @@ func OwnerProfile(ctx *context.Context) { func userProfile(ctx *context.Context) { // check view permissions if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) { - ctx.NotFound("user", fmt.Errorf("%s", ctx.ContextUser.Name)) + ctx.NotFound(fmt.Errorf("%s", ctx.ContextUser.Name)) return } @@ -325,7 +325,7 @@ func ActionUserFollow(ctx *context.Context) { if err != nil { log.Error("Failed to apply action %q: %v", ctx.FormString("action"), err) - ctx.Error(http.StatusBadRequest, fmt.Sprintf("Action %q failed", ctx.FormString("action"))) + ctx.HTTPError(http.StatusBadRequest, fmt.Sprintf("Action %q failed", ctx.FormString("action"))) return } @@ -340,5 +340,5 @@ func ActionUserFollow(ctx *context.Context) { return } log.Error("Failed to apply action %q: unsupported context user type: %s", ctx.FormString("action"), ctx.ContextUser.Type) - ctx.Error(http.StatusBadRequest, fmt.Sprintf("Action %q failed", ctx.FormString("action"))) + ctx.HTTPError(http.StatusBadRequest, fmt.Sprintf("Action %q failed", ctx.FormString("action"))) } diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index 3acc3c7a543e5..94577832a9b12 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -37,7 +37,7 @@ const ( // Account renders change user's password, user's email and user suicide page func Account(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials, setting.UserFeatureDeletion) && !setting.Service.EnableNotifyMail { - ctx.NotFound("Not Found", fmt.Errorf("account setting are not allowed to be changed")) + ctx.NotFound(fmt.Errorf("account setting are not allowed to be changed")) return } @@ -54,7 +54,7 @@ func Account(ctx *context.Context) { // AccountPost response for change user's password func AccountPost(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials) { - ctx.NotFound("Not Found", fmt.Errorf("password setting is not allowed to be changed")) + ctx.NotFound(fmt.Errorf("password setting is not allowed to be changed")) return } @@ -105,7 +105,7 @@ func AccountPost(ctx *context.Context) { // EmailPost response for change user's email func EmailPost(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials) { - ctx.NotFound("Not Found", fmt.Errorf("emails are not allowed to be changed")) + ctx.NotFound(fmt.Errorf("emails are not allowed to be changed")) return } @@ -239,7 +239,7 @@ func EmailPost(ctx *context.Context) { // DeleteEmail response for delete user's email func DeleteEmail(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials) { - ctx.NotFound("Not Found", fmt.Errorf("emails are not allowed to be changed")) + ctx.NotFound(fmt.Errorf("emails are not allowed to be changed")) return } email, err := user_model.GetEmailAddressByID(ctx, ctx.Doer.ID, ctx.FormInt64("id")) @@ -261,7 +261,7 @@ func DeleteEmail(ctx *context.Context) { // DeleteAccount render user suicide page and response for delete user himself func DeleteAccount(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureDeletion) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go index 127aed9845e95..17e32f54039a2 100644 --- a/routers/web/user/setting/keys.go +++ b/routers/web/user/setting/keys.go @@ -26,7 +26,7 @@ const ( // Keys render user's SSH/GPG public keys page func Keys(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys, setting.UserFeatureManageGPGKeys) { - ctx.NotFound("Not Found", fmt.Errorf("keys setting is not allowed to be changed")) + ctx.NotFound(fmt.Errorf("keys setting is not allowed to be changed")) return } @@ -87,7 +87,7 @@ func KeysPost(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/user/settings/keys") case "gpg": if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageGPGKeys) { - ctx.NotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) + ctx.NotFound(fmt.Errorf("gpg keys setting is not allowed to be visited")) return } @@ -168,7 +168,7 @@ func KeysPost(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/user/settings/keys") case "ssh": if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) { - ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + ctx.NotFound(fmt.Errorf("ssh keys setting is not allowed to be visited")) return } @@ -212,7 +212,7 @@ func KeysPost(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/user/settings/keys") case "verify_ssh": if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) { - ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + ctx.NotFound(fmt.Errorf("ssh keys setting is not allowed to be visited")) return } @@ -249,7 +249,7 @@ func DeleteKey(ctx *context.Context) { switch ctx.FormString("type") { case "gpg": if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageGPGKeys) { - ctx.NotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) + ctx.NotFound(fmt.Errorf("gpg keys setting is not allowed to be visited")) return } if err := asymkey_model.DeleteGPGKey(ctx, ctx.Doer, ctx.FormInt64("id")); err != nil { @@ -259,7 +259,7 @@ func DeleteKey(ctx *context.Context) { } case "ssh": if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) { - ctx.NotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + ctx.NotFound(fmt.Errorf("ssh keys setting is not allowed to be visited")) return } diff --git a/routers/web/user/setting/oauth2_common.go b/routers/web/user/setting/oauth2_common.go index 783deca710f58..d4da468a856a7 100644 --- a/routers/web/user/setting/oauth2_common.go +++ b/routers/web/user/setting/oauth2_common.go @@ -76,14 +76,14 @@ func (oa *OAuth2CommonHandlers) EditShow(ctx *context.Context) { app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.PathParamInt64("id")) if err != nil { if auth.IsErrOAuthApplicationNotFound(err) { - ctx.NotFound("Application not found", err) + ctx.NotFound(err) return } ctx.ServerError("GetOAuth2ApplicationByID", err) return } if app.UID != oa.OwnerID { - ctx.NotFound("Application not found", nil) + ctx.NotFound(nil) return } ctx.Data["App"] = app @@ -98,14 +98,14 @@ func (oa *OAuth2CommonHandlers) EditSave(ctx *context.Context) { app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.PathParamInt64("id")) if err != nil { if auth.IsErrOAuthApplicationNotFound(err) { - ctx.NotFound("Application not found", err) + ctx.NotFound(err) return } ctx.ServerError("GetOAuth2ApplicationByID", err) return } if app.UID != oa.OwnerID { - ctx.NotFound("Application not found", nil) + ctx.NotFound(nil) return } ctx.Data["App"] = app @@ -135,14 +135,14 @@ func (oa *OAuth2CommonHandlers) RegenerateSecret(ctx *context.Context) { app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.PathParamInt64("id")) if err != nil { if auth.IsErrOAuthApplicationNotFound(err) { - ctx.NotFound("Application not found", err) + ctx.NotFound(err) return } ctx.ServerError("GetOAuth2ApplicationByID", err) return } if app.UID != oa.OwnerID { - ctx.NotFound("Application not found", nil) + ctx.NotFound(nil) return } ctx.Data["App"] = app diff --git a/routers/web/user/setting/security/2fa.go b/routers/web/user/setting/security/2fa.go index 7bb10248e8b7a..e5315efc74ba8 100644 --- a/routers/web/user/setting/security/2fa.go +++ b/routers/web/user/setting/security/2fa.go @@ -27,7 +27,7 @@ import ( // RegenerateScratchTwoFactor regenerates the user's 2FA scratch code. func RegenerateScratchTwoFactor(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageMFA) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -63,7 +63,7 @@ func RegenerateScratchTwoFactor(ctx *context.Context) { // DisableTwoFactor deletes the user's 2FA settings. func DisableTwoFactor(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageMFA) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -157,7 +157,7 @@ func twofaGenerateSecretAndQr(ctx *context.Context) bool { // EnrollTwoFactor shows the page where the user can enroll into 2FA. func EnrollTwoFactor(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageMFA) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -187,7 +187,7 @@ func EnrollTwoFactor(ctx *context.Context) { // EnrollTwoFactorPost handles enrolling the user into 2FA. func EnrollTwoFactorPost(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageMFA) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } diff --git a/routers/web/user/setting/security/openid.go b/routers/web/user/setting/security/openid.go index 30eb6f63f89a0..9a57657912ed2 100644 --- a/routers/web/user/setting/security/openid.go +++ b/routers/web/user/setting/security/openid.go @@ -18,7 +18,7 @@ import ( // OpenIDPost response for change user's openid func OpenIDPost(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -111,7 +111,7 @@ func settingsOpenIDVerify(ctx *context.Context) { // DeleteOpenID response for delete user's openid func DeleteOpenID(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -128,7 +128,7 @@ func DeleteOpenID(ctx *context.Context) { // ToggleOpenIDVisibility response for toggle visibility of user's openid func ToggleOpenIDVisibility(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } diff --git a/routers/web/user/setting/security/security.go b/routers/web/user/setting/security/security.go index 38d1910e2d71b..cc4c44993af61 100644 --- a/routers/web/user/setting/security/security.go +++ b/routers/web/user/setting/security/security.go @@ -27,7 +27,7 @@ const ( func Security(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageMFA, setting.UserFeatureManageCredentials) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -47,7 +47,7 @@ func Security(ctx *context.Context) { // DeleteAccountLink delete a single account link func DeleteAccountLink(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } diff --git a/routers/web/user/setting/security/webauthn.go b/routers/web/user/setting/security/webauthn.go index 70bfaac6e0943..63721343df4a2 100644 --- a/routers/web/user/setting/security/webauthn.go +++ b/routers/web/user/setting/security/webauthn.go @@ -25,7 +25,7 @@ import ( // WebAuthnRegister initializes the webauthn registration procedure func WebAuthnRegister(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageMFA) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -41,7 +41,7 @@ func WebAuthnRegister(ctx *context.Context) { return } if cred != nil { - ctx.Error(http.StatusConflict, "Name already taken") + ctx.HTTPError(http.StatusConflict, "Name already taken") return } @@ -72,7 +72,7 @@ func WebAuthnRegister(ctx *context.Context) { // WebauthnRegisterPost receives the response of the security key func WebauthnRegisterPost(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageMFA) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } @@ -109,7 +109,7 @@ func WebauthnRegisterPost(ctx *context.Context) { return } if dbCred != nil { - ctx.Error(http.StatusConflict, "Name already taken") + ctx.HTTPError(http.StatusConflict, "Name already taken") return } @@ -127,7 +127,7 @@ func WebauthnRegisterPost(ctx *context.Context) { // WebauthnDelete deletes an security key by id func WebauthnDelete(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageMFA) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } diff --git a/routers/web/user/stop_watch.go b/routers/web/user/stop_watch.go index 38f74ea455454..1d1cc61cc925d 100644 --- a/routers/web/user/stop_watch.go +++ b/routers/web/user/stop_watch.go @@ -19,19 +19,19 @@ func GetStopwatches(ctx *context.Context) { PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), }) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } count, err := issues_model.CountUserStopwatches(ctx, ctx.Doer.ID) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } apiSWs, err := convert.ToStopWatches(ctx, sws) if err != nil { - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.HTTPError(http.StatusInternalServerError, err.Error()) return } diff --git a/routers/web/web.go b/routers/web/web.go index f5bd6a92979db..bca20b88abd93 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -119,7 +119,7 @@ func webAuth(authMethod auth_service.Method) func(*context.Context) { ar, err := common.AuthShared(ctx.Base, ctx.Session, authMethod) if err != nil { log.Error("Failed to verify user: %v", err) - ctx.Error(http.StatusUnauthorized, "Failed to authenticate user") + ctx.HTTPError(http.StatusUnauthorized, "Failed to authenticate user") return } ctx.Doer = ar.Doer @@ -154,7 +154,7 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.Cont if ctx.Doer.MustChangePassword { if ctx.Req.URL.Path != "/user/settings/change_password" { if strings.HasPrefix(ctx.Req.UserAgent(), "git") { - ctx.Error(http.StatusUnauthorized, ctx.Locale.TrString("auth.must_change_password")) + ctx.HTTPError(http.StatusUnauthorized, ctx.Locale.TrString("auth.must_change_password")) return } ctx.Data["Title"] = ctx.Tr("auth.must_change_password") @@ -211,7 +211,7 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.Cont if options.AdminRequired { if !ctx.Doer.IsAdmin { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } ctx.Data["PageIsAdmin"] = true @@ -307,35 +307,35 @@ func registerRoutes(m *web.Router) { linkAccountEnabled := func(ctx *context.Context) { if !setting.Service.EnableOpenIDSignIn && !setting.Service.EnableOpenIDSignUp && !setting.OAuth2.Enabled { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } } openIDSignInEnabled := func(ctx *context.Context) { if !setting.Service.EnableOpenIDSignIn { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } } openIDSignUpEnabled := func(ctx *context.Context) { if !setting.Service.EnableOpenIDSignUp { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } } oauth2Enabled := func(ctx *context.Context) { if !setting.OAuth2.Enabled { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } } reqMilestonesDashboardPageEnabled := func(ctx *context.Context) { if !setting.Service.ShowMilestonesDashboardPage { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } } @@ -343,56 +343,56 @@ func registerRoutes(m *web.Router) { // webhooksEnabled requires webhooks to be enabled by admin. webhooksEnabled := func(ctx *context.Context) { if setting.DisableWebhooks { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } } starsEnabled := func(ctx *context.Context) { if setting.Repository.DisableStars { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } } lfsServerEnabled := func(ctx *context.Context) { if !setting.LFS.StartServer { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } } federationEnabled := func(ctx *context.Context) { if !setting.Federation.Enabled { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } } dlSourceEnabled := func(ctx *context.Context) { if setting.Repository.DisableDownloadSourceArchives { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } } sitemapEnabled := func(ctx *context.Context) { if !setting.Other.EnableSitemap { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } } packagesEnabled := func(ctx *context.Context) { if !setting.Packages.Enabled { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } } feedEnabled := func(ctx *context.Context) { if !setting.Other.EnableFeed { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } } @@ -401,18 +401,18 @@ func registerRoutes(m *web.Router) { return func(ctx *context.Context) { // only check global disabled units when ignoreGlobal is false if !ignoreGlobal && unitType.UnitGlobalDisabled() { - ctx.NotFound("Repo unit is is disabled: "+unitType.LogString(), nil) + ctx.NotFound(nil) return } if ctx.ContextUser == nil { - ctx.NotFound("ContextUser is nil", nil) + ctx.NotFound(nil) return } if ctx.ContextUser.IsOrganization() { if ctx.Org.Organization.UnitPermission(ctx, ctx.Doer, unitType) < accessMode { - ctx.NotFound("ContextUser is org but doer has no access to unit", nil) + ctx.NotFound(nil) return } } @@ -506,7 +506,7 @@ func registerRoutes(m *web.Router) { m.Get("/organizations", explore.Organizations) m.Get("/code", func(ctx *context.Context) { if unit.TypeCode.UnitGlobalDisabled() { - ctx.NotFound("Repo unit code is disabled", nil) + ctx.NotFound(nil) return } }, explore.Code) @@ -847,7 +847,7 @@ func registerRoutes(m *web.Router) { reqPackageAccess := func(accessMode perm.AccessMode) func(ctx *context.Context) { return func(ctx *context.Context) { if ctx.Package.AccessMode < accessMode && !ctx.IsUserSiteAdmin() { - ctx.NotFound("", nil) + ctx.NotFound(nil) } } } @@ -858,12 +858,12 @@ func registerRoutes(m *web.Router) { switch { case ctx.ContextUser.Visibility == structs.VisibleTypePrivate: if ctx.Doer == nil || (ctx.ContextUser.ID != ctx.Doer.ID && !ctx.Doer.IsAdmin) { - ctx.NotFound("Visit Project", nil) + ctx.NotFound(nil) return } case ctx.ContextUser.Visibility == structs.VisibleTypeLimited: if ctx.Doer == nil { - ctx.NotFound("Visit Project", nil) + ctx.NotFound(nil) return } } @@ -1052,7 +1052,7 @@ func registerRoutes(m *web.Router) { }) }, reqSignIn, reqUnitAccess(unit.TypeProjects, perm.AccessModeWrite, true), func(ctx *context.Context) { if ctx.ContextUser.IsIndividual() && ctx.ContextUser.ID != ctx.Doer.ID { - ctx.NotFound("NewProject", nil) + ctx.NotFound(nil) return } }) @@ -1639,6 +1639,6 @@ func registerRoutes(m *web.Router) { m.NotFound(func(w http.ResponseWriter, req *http.Request) { ctx := context.GetWebContext(req.Context()) defer routing.RecordFuncInfo(ctx, routing.GetFuncInfo(ctx.NotFound, "WebNotFound"))() - ctx.NotFound("", nil) + ctx.NotFound(nil) }) } diff --git a/routers/web/webfinger.go b/routers/web/webfinger.go index a87c426b3baa1..afcfdc82528a5 100644 --- a/routers/web/webfinger.go +++ b/routers/web/webfinger.go @@ -39,7 +39,7 @@ func WebfingerQuery(ctx *context.Context) { resource, err := url.Parse(ctx.FormTrim("resource")) if err != nil { - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } @@ -50,11 +50,11 @@ func WebfingerQuery(ctx *context.Context) { // allow only the current host parts := strings.SplitN(resource.Opaque, "@", 2) if len(parts) != 2 { - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } if parts[1] != appURL.Host { - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } @@ -65,21 +65,21 @@ func WebfingerQuery(ctx *context.Context) { err = user_model.ErrUserNotExist{} } default: - ctx.Error(http.StatusBadRequest) + ctx.HTTPError(http.StatusBadRequest) return } if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) } else { log.Error("Error getting user: %s Error: %v", resource.Opaque, err) - ctx.Error(http.StatusInternalServerError) + ctx.HTTPError(http.StatusInternalServerError) } return } if !user_model.IsUserVisibleToViewer(ctx, u, ctx.Doer) { - ctx.Error(http.StatusNotFound) + ctx.HTTPError(http.StatusNotFound) return } diff --git a/services/actions/workflow.go b/services/actions/workflow.go index 4470b60c64091..9aecad171b4c1 100644 --- a/services/actions/workflow.go +++ b/services/actions/workflow.go @@ -104,13 +104,13 @@ func EnableOrDisableWorkflow(ctx *context.APIContext, workflowID string, isEnabl func ListActionWorkflows(ctx *context.APIContext) ([]*api.ActionWorkflow, error) { defaultBranchCommit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) if err != nil { - ctx.Error(http.StatusInternalServerError, "WorkflowDefaultBranchError", err.Error()) + ctx.APIErrorInternal(err) return nil, err } entries, err := actions.ListWorkflows(defaultBranchCommit) if err != nil { - ctx.Error(http.StatusNotFound, "WorkflowListNotFound", err.Error()) + ctx.APIError(http.StatusNotFound, err.Error()) return nil, err } diff --git a/services/context/api.go b/services/context/api.go index baf4131edc1f5..230c3456d1996 100644 --- a/services/context/api.go +++ b/services/context/api.go @@ -5,6 +5,7 @@ package context import ( + "errors" "fmt" "net/http" "net/url" @@ -17,6 +18,7 @@ import ( "code.gitea.io/gitea/modules/httpcache" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" web_types "code.gitea.io/gitea/modules/web/types" ) @@ -106,14 +108,28 @@ type APIRepoArchivedError struct { APIError } -// ServerError responds with error message, status is 500 -func (ctx *APIContext) ServerError(title string, err error) { - ctx.Error(http.StatusInternalServerError, title, err) +// APIErrorInternal responds with error message, status is 500 +func (ctx *APIContext) APIErrorInternal(err error) { + ctx.apiErrorInternal(1, err) } -// Error responds with an error message to client with given obj as the message. +func (ctx *APIContext) apiErrorInternal(skip int, err error) { + log.ErrorWithSkip(skip+1, "InternalServerError: %v", err) + + var message string + if !setting.IsProd || (ctx.Doer != nil && ctx.Doer.IsAdmin) { + message = err.Error() + } + + ctx.JSON(http.StatusInternalServerError, APIError{ + Message: message, + URL: setting.API.SwaggerURL, + }) +} + +// 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) Error(status int, title string, obj any) { +func (ctx *APIContext) APIError(status int, obj any) { var message string if err, ok := obj.(error); ok { message = err.Error() @@ -122,7 +138,7 @@ func (ctx *APIContext) Error(status int, title string, obj any) { } if status == http.StatusInternalServerError { - log.ErrorWithSkip(1, "%s: %s", title, message) + log.ErrorWithSkip(1, "APIError: %s", message) if setting.IsProd && !(ctx.Doer != nil && ctx.Doer.IsAdmin) { message = "" @@ -135,22 +151,6 @@ func (ctx *APIContext) Error(status int, title string, obj any) { }) } -// InternalServerError responds with an error message to the client with the error as a message -// and the file and line of the caller. -func (ctx *APIContext) InternalServerError(err error) { - log.ErrorWithSkip(1, "InternalServerError: %v", err) - - var message string - if !setting.IsProd || (ctx.Doer != nil && ctx.Doer.IsAdmin) { - message = err.Error() - } - - ctx.JSON(http.StatusInternalServerError, APIError{ - Message: message, - URL: setting.API.SwaggerURL, - }) -} - type apiContextKeyType struct{} var apiContextKey = apiContextKeyType{} @@ -210,7 +210,7 @@ func (ctx *APIContext) SetLinkHeader(total, pageSize int) { } } -// APIContexter returns apicontext as middleware +// APIContexter returns APIContext middleware func APIContexter() func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { @@ -227,7 +227,7 @@ func APIContexter() func(http.Handler) http.Handler { // If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid. if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") { if err := ctx.Req.ParseMultipartForm(setting.Attachment.MaxSize << 20); err != nil && !strings.Contains(err.Error(), "EOF") { // 32MB max size - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } } @@ -240,9 +240,9 @@ func APIContexter() func(http.Handler) http.Handler { } } -// NotFound handles 404s for APIContext +// APIErrorNotFound handles 404s for APIContext // String will replace message, errors will be added to a slice -func (ctx *APIContext) NotFound(objs ...any) { +func (ctx *APIContext) APIErrorNotFound(objs ...any) { message := ctx.Locale.TrString("error.not_found") var errors []string for _, obj := range objs { @@ -279,7 +279,7 @@ func ReferencesGitRepo(allowEmpty ...bool) func(ctx *APIContext) { var err error ctx.Repo.GitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository) if err != nil { - ctx.Error(http.StatusInternalServerError, fmt.Sprintf("Open Repository %v failed", ctx.Repo.Repository.FullName()), err) + ctx.APIErrorInternal(err) return } } @@ -292,7 +292,7 @@ func RepoRefForAPI(next http.Handler) http.Handler { ctx := GetAPIContext(req) if ctx.Repo.GitRepo == nil { - ctx.InternalServerError(fmt.Errorf("no open git repo")) + ctx.APIErrorInternal(fmt.Errorf("no open git repo")) return } @@ -302,14 +302,14 @@ func RepoRefForAPI(next http.Handler) http.Handler { if ctx.Repo.GitRepo.IsBranchExist(refName) { ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() } else if ctx.Repo.GitRepo.IsTagExist(refName) { ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName) if err != nil { - ctx.InternalServerError(err) + ctx.APIErrorInternal(err) return } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() @@ -317,11 +317,11 @@ func RepoRefForAPI(next http.Handler) http.Handler { ctx.Repo.CommitID = refName ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName) if err != nil { - ctx.NotFound("GetCommit", err) + ctx.APIErrorNotFound("GetCommit", err) return } } else { - ctx.NotFound(fmt.Errorf("not exist: '%s'", ctx.PathParam("*"))) + ctx.APIErrorNotFound(fmt.Errorf("not exist: '%s'", ctx.PathParam("*"))) return } @@ -350,12 +350,12 @@ func (ctx *APIContext) GetErrMsg() string { // 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(logMsg string, errCheck func(error) bool, logErr error) { - if errCheck(logErr) { +func (ctx *APIContext) NotFoundOrServerError(err error) { + if errors.Is(err, util.ErrNotExist) { ctx.JSON(http.StatusNotFound, nil) return } - ctx.Error(http.StatusInternalServerError, "NotFoundOrServerError", logMsg) + ctx.APIErrorInternal(err) } // IsUserSiteAdmin returns true if current user is a site admin @@ -368,7 +368,7 @@ func (ctx *APIContext) IsUserRepoAdmin() bool { return ctx.Repo.IsAdmin() } -// IsUserRepoWriter returns true if current user has write privilege in current repo +// IsUserRepoWriter returns true if current user has "write" privilege in current repo func (ctx *APIContext) IsUserRepoWriter(unitTypes []unit.Type) bool { for _, unitType := range unitTypes { if ctx.Repo.CanWrite(unitType) { diff --git a/services/context/base.go b/services/context/base.go index 4d1c3659a2646..3701668bf633a 100644 --- a/services/context/base.go +++ b/services/context/base.go @@ -81,8 +81,8 @@ func (b *Base) RespHeader() http.Header { return b.Resp.Header() } -// Error returned an error to web browser -func (b *Base) Error(status int, contents ...string) { +// HTTPError returned an error to web browser +func (b *Base) HTTPError(status int, contents ...string) { v := http.StatusText(status) if len(contents) > 0 { v = contents[0] diff --git a/services/context/context_response.go b/services/context/context_response.go index c7044791eb6e2..61b432395a56b 100644 --- a/services/context/context_response.go +++ b/services/context/context_response.go @@ -28,7 +28,7 @@ import ( func RedirectToUser(ctx *Base, userName string, redirectUserID int64) { user, err := user_model.GetUserByID(ctx, redirectUserID) if err != nil { - ctx.Error(http.StatusInternalServerError, "unable to get user") + ctx.HTTPError(http.StatusInternalServerError, "unable to get user") return } @@ -122,8 +122,8 @@ func (ctx *Context) RenderWithErr(msg any, tpl templates.TplName, form any) { } // NotFound displays a 404 (Not Found) page and prints the given error, if any. -func (ctx *Context) NotFound(logMsg string, logErr error) { - ctx.notFoundInternal(logMsg, logErr) +func (ctx *Context) NotFound(logErr error) { + ctx.notFoundInternal("", logErr) } func (ctx *Context) notFoundInternal(logMsg string, logErr error) { diff --git a/services/context/org.go b/services/context/org.go index 3f73165076f60..992a48afa0710 100644 --- a/services/context/org.go +++ b/services/context/org.go @@ -51,7 +51,7 @@ func GetOrganizationByParams(ctx *Context) { if err == nil { RedirectToUser(ctx.Base, orgName, redirectUserID) } else if user_model.IsErrUserRedirectNotExist(err) { - ctx.NotFound("GetUserByName", err) + ctx.NotFound(err) } else { ctx.ServerError("LookupUserRedirect", err) } @@ -93,7 +93,7 @@ func OrgAssignment(opts OrgAssignmentOptions) func(ctx *Context) { // Handle Visibility if org.Visibility != structs.VisibleTypePublic && !ctx.IsSigned { // We must be signed in to see limited or private organizations - ctx.NotFound("OrgAssignment", err) + ctx.NotFound(err) return } @@ -142,7 +142,7 @@ func OrgAssignment(opts OrgAssignmentOptions) func(ctx *Context) { ctx.Data["SignedUser"] = &user_model.User{} } if (opts.RequireMember && !ctx.Org.IsMember) || (opts.RequireOwner && !ctx.Org.IsOwner) { - ctx.NotFound("OrgAssignment", err) + ctx.NotFound(err) return } ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner @@ -218,20 +218,20 @@ func OrgAssignment(opts OrgAssignmentOptions) func(ctx *Context) { } if !teamExists { - ctx.NotFound("OrgAssignment", err) + ctx.NotFound(err) return } ctx.Data["IsTeamMember"] = ctx.Org.IsTeamMember if opts.RequireTeamMember && !ctx.Org.IsTeamMember { - ctx.NotFound("OrgAssignment", err) + ctx.NotFound(err) return } ctx.Org.IsTeamAdmin = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.AccessMode >= perm.AccessModeAdmin ctx.Data["IsTeamAdmin"] = ctx.Org.IsTeamAdmin if opts.RequireTeamAdmin && !ctx.Org.IsTeamAdmin { - ctx.NotFound("OrgAssignment", err) + ctx.NotFound(err) return } } diff --git a/services/context/package.go b/services/context/package.go index e32ba3b481c6b..64bb4f3ecd2f9 100644 --- a/services/context/package.go +++ b/services/context/package.go @@ -33,15 +33,15 @@ 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, title string, obj any) { + errorFn := func(status int, obj any) { err, ok := obj.(error) if !ok { err = fmt.Errorf("%s", obj) } if status == http.StatusNotFound { - ctx.NotFound(title, err) + ctx.NotFound(err) } else { - ctx.ServerError(title, err) + ctx.ServerError("PackageAssignment", err) } } paCtx := &packageAssignmentCtx{Base: ctx.Base, Doer: ctx.Doer, ContextUser: ctx.ContextUser} @@ -53,18 +53,18 @@ func PackageAssignment() func(ctx *Context) { func PackageAssignmentAPI() func(ctx *APIContext) { return func(ctx *APIContext) { paCtx := &packageAssignmentCtx{Base: ctx.Base, Doer: ctx.Doer, ContextUser: ctx.ContextUser} - ctx.Package = packageAssignment(paCtx, ctx.Error) + ctx.Package = packageAssignment(paCtx, ctx.APIError) } } -func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, string, any)) *Package { +func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, any)) *Package { pkg := &Package{ Owner: ctx.ContextUser, } var err error pkg.AccessMode, err = determineAccessMode(ctx.Base, pkg, ctx.Doer) if err != nil { - errCb(http.StatusInternalServerError, "determineAccessMode", err) + errCb(http.StatusInternalServerError, fmt.Errorf("determineAccessMode: %w", err)) return pkg } @@ -75,16 +75,16 @@ func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, string, any)) pv, err := packages_model.GetVersionByNameAndVersion(ctx, pkg.Owner.ID, packages_model.Type(packageType), name, version) if err != nil { if err == packages_model.ErrPackageNotExist { - errCb(http.StatusNotFound, "GetVersionByNameAndVersion", err) + errCb(http.StatusNotFound, fmt.Errorf("GetVersionByNameAndVersion: %w", err)) } else { - errCb(http.StatusInternalServerError, "GetVersionByNameAndVersion", err) + errCb(http.StatusInternalServerError, fmt.Errorf("GetVersionByNameAndVersion: %w", err)) } return pkg } pkg.Descriptor, err = packages_model.GetPackageDescriptor(ctx, pv) if err != nil { - errCb(http.StatusInternalServerError, "GetPackageDescriptor", err) + errCb(http.StatusInternalServerError, fmt.Errorf("GetPackageDescriptor: %w", err)) return pkg } } diff --git a/services/context/permission.go b/services/context/permission.go index 0d69ccc4a405c..7055f798da3f0 100644 --- a/services/context/permission.go +++ b/services/context/permission.go @@ -15,7 +15,7 @@ import ( func RequireRepoAdmin() func(ctx *Context) { return func(ctx *Context) { if !ctx.IsSigned || !ctx.Repo.IsAdmin() { - ctx.NotFound("RequireRepoAdmin denies the request", nil) + ctx.NotFound(nil) return } } @@ -25,7 +25,7 @@ func RequireRepoAdmin() func(ctx *Context) { func CanWriteToBranch() func(ctx *Context) { return func(ctx *Context) { if !ctx.Repo.CanWriteToBranch(ctx, ctx.Doer, ctx.Repo.BranchName) { - ctx.NotFound("CanWriteToBranch denies permission", nil) + ctx.NotFound(nil) return } } @@ -39,7 +39,7 @@ func RequireUnitWriter(unitTypes ...unit.Type) func(ctx *Context) { return } } - ctx.NotFound("RequireUnitWriter denies the request", nil) + ctx.NotFound(nil) } } @@ -54,7 +54,7 @@ func RequireUnitReader(unitTypes ...unit.Type) func(ctx *Context) { return } } - ctx.NotFound("RequireUnitReader denies the request", nil) + ctx.NotFound(nil) } } @@ -78,7 +78,7 @@ func CheckRepoScopedToken(ctx *Context, repo *repo_model.Repository, level auth_ } if publicOnly && repo.IsPrivate { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } @@ -89,7 +89,7 @@ func CheckRepoScopedToken(ctx *Context, repo *repo_model.Repository, level auth_ } if !scopeMatched { - ctx.Error(http.StatusForbidden) + ctx.HTTPError(http.StatusForbidden) return } } diff --git a/services/context/repo.go b/services/context/repo.go index 1cb35b9b83771..e63e3e53175f9 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -89,7 +89,7 @@ func (r *Repository) GetObjectFormat() git.ObjectFormat { func RepoMustNotBeArchived() func(ctx *Context) { return func(ctx *Context) { if ctx.Repo.Repository.IsArchived { - ctx.NotFound("IsArchived", errors.New(ctx.Locale.TrString("repo.archive.title"))) + ctx.NotFound(errors.New(ctx.Locale.TrString("repo.archive.title"))) } } } @@ -315,7 +315,7 @@ func RedirectToRepo(ctx *Base, redirectRepoID int64) { repo, err := repo_model.GetRepositoryByID(ctx, redirectRepoID) if err != nil { log.Error("GetRepositoryByID: %v", err) - ctx.Error(http.StatusInternalServerError, "GetRepositoryByID") + ctx.HTTPError(http.StatusInternalServerError, "GetRepositoryByID") return } @@ -349,7 +349,7 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) { EarlyResponseForGoGetMeta(ctx) return } - ctx.NotFound("no access right", nil) + ctx.NotFound(nil) return } ctx.Data["Permission"] = &ctx.Repo.Permission @@ -402,7 +402,7 @@ func RepoAssignment(ctx *Context) { if redirectUserID, err := user_model.LookupUserRedirect(ctx, userName); err == nil { RedirectToUser(ctx.Base, userName, redirectUserID) } else if user_model.IsErrUserRedirectNotExist(err) { - ctx.NotFound("GetUserByName", nil) + ctx.NotFound(nil) } else { ctx.ServerError("LookupUserRedirect", err) } @@ -447,7 +447,7 @@ func RepoAssignment(ctx *Context) { EarlyResponseForGoGetMeta(ctx) return } - ctx.NotFound("GetRepositoryByName", nil) + ctx.NotFound(nil) } else { ctx.ServerError("LookupRepoRedirect", err) } @@ -870,7 +870,7 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) { ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refShortName) if err != nil { if git.IsErrNotExist(err) { - ctx.NotFound("GetTagCommit", err) + ctx.NotFound(err) return } ctx.ServerError("GetTagCommit", err) @@ -883,7 +883,7 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) { ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refShortName) if err != nil { - ctx.NotFound("GetCommit", err) + ctx.NotFound(err) return } // If short commit ID add canonical link header @@ -892,7 +892,7 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) { ctx.RespHeader().Set("Link", fmt.Sprintf(`<%s>; rel="canonical"`, canonicalURL)) } } else { - ctx.NotFound("RepoRef invalid repo", fmt.Errorf("branch or tag not exist: %s", refShortName)) + ctx.NotFound(fmt.Errorf("branch or tag not exist: %s", refShortName)) return } @@ -945,7 +945,7 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) { func GitHookService() func(ctx *Context) { return func(ctx *Context) { if !ctx.Doer.CanEditGitHook() { - ctx.NotFound("GitHookService", nil) + ctx.NotFound(nil) return } } diff --git a/services/context/user.go b/services/context/user.go index dbc35e198d498..c09ded833969c 100644 --- a/services/context/user.go +++ b/services/context/user.go @@ -14,15 +14,15 @@ 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, title string, obj any) { + errorFn := func(status int, obj any) { err, ok := obj.(error) if !ok { err = fmt.Errorf("%s", obj) } if status == http.StatusNotFound { - ctx.NotFound(title, err) + ctx.NotFound(err) } else { - ctx.ServerError(title, err) + ctx.ServerError("UserAssignmentWeb", err) } } ctx.ContextUser = userAssignment(ctx.Base, ctx.Doer, errorFn) @@ -42,9 +42,9 @@ func UserIDAssignmentAPI() func(ctx *APIContext) { ctx.ContextUser, err = user_model.GetUserByID(ctx, userID) if err != nil { if user_model.IsErrUserNotExist(err) { - ctx.Error(http.StatusNotFound, "GetUserByID", err) + ctx.APIError(http.StatusNotFound, err) } else { - ctx.Error(http.StatusInternalServerError, "GetUserByID", err) + ctx.APIErrorInternal(err) } } } @@ -54,11 +54,11 @@ func UserIDAssignmentAPI() func(ctx *APIContext) { // UserAssignmentAPI returns a middleware to handle context-user assignment for api routes func UserAssignmentAPI() func(ctx *APIContext) { return func(ctx *APIContext) { - ctx.ContextUser = userAssignment(ctx.Base, ctx.Doer, ctx.Error) + ctx.ContextUser = userAssignment(ctx.Base, ctx.Doer, ctx.APIError) } } -func userAssignment(ctx *Base, doer *user_model.User, errCb func(int, string, any)) (contextUser *user_model.User) { +func userAssignment(ctx *Base, doer *user_model.User, errCb func(int, any)) (contextUser *user_model.User) { username := ctx.PathParam("username") if doer != nil && doer.LowerName == strings.ToLower(username) { @@ -71,12 +71,12 @@ func userAssignment(ctx *Base, doer *user_model.User, errCb func(int, string, an if redirectUserID, err := user_model.LookupUserRedirect(ctx, username); err == nil { RedirectToUser(ctx, username, redirectUserID) } else if user_model.IsErrUserRedirectNotExist(err) { - errCb(http.StatusNotFound, "GetUserByName", err) + errCb(http.StatusNotFound, err) } else { - errCb(http.StatusInternalServerError, "LookupUserRedirect", err) + errCb(http.StatusInternalServerError, fmt.Errorf("LookupUserRedirect: %w", err)) } } else { - errCb(http.StatusInternalServerError, "GetUserByName", err) + errCb(http.StatusInternalServerError, fmt.Errorf("GetUserByName: %w", err)) } } } diff --git a/services/convert/issue.go b/services/convert/issue.go index 62d0a3b3e6827..7f386e629337d 100644 --- a/services/convert/issue.go +++ b/services/convert/issue.go @@ -41,6 +41,9 @@ func toIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Iss if err := issue.LoadAttachments(ctx); err != nil { return &api.Issue{} } + if err := issue.LoadPinOrder(ctx); err != nil { + return &api.Issue{} + } apiIssue := &api.Issue{ ID: issue.ID, @@ -55,7 +58,7 @@ func toIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Iss Comments: issue.NumComments, Created: issue.CreatedUnix.AsTime(), Updated: issue.UpdatedUnix.AsTime(), - PinOrder: issue.PinOrder, + PinOrder: util.Iif(issue.PinOrder == -1, 0, issue.PinOrder), // -1 means loaded with no pin order } if issue.Repo != nil { @@ -122,6 +125,7 @@ func toIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Iss // ToIssueList converts an IssueList to API format func ToIssueList(ctx context.Context, doer *user_model.User, il issues_model.IssueList) []*api.Issue { result := make([]*api.Issue, len(il)) + _ = il.LoadPinOrder(ctx) for i := range il { result[i] = ToIssue(ctx, doer, il[i]) } @@ -131,6 +135,7 @@ func ToIssueList(ctx context.Context, doer *user_model.User, il issues_model.Iss // ToAPIIssueList converts an IssueList to API format func ToAPIIssueList(ctx context.Context, doer *user_model.User, il issues_model.IssueList) []*api.Issue { result := make([]*api.Issue, len(il)) + _ = il.LoadPinOrder(ctx) for i := range il { result[i] = ToAPIIssue(ctx, doer, il[i]) } diff --git a/services/convert/pull.go b/services/convert/pull.go index 209d2bd79d2e1..ad4f08fa9178d 100644 --- a/services/convert/pull.go +++ b/services/convert/pull.go @@ -93,7 +93,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u Deadline: apiIssue.Deadline, Created: pr.Issue.CreatedUnix.AsTimePtr(), Updated: pr.Issue.UpdatedUnix.AsTimePtr(), - PinOrder: apiIssue.PinOrder, + PinOrder: util.Iif(apiIssue.PinOrder == -1, 0, apiIssue.PinOrder), // output "[]" rather than null to align to github outputs RequestedReviewers: []*api.User{}, @@ -304,6 +304,9 @@ func ToAPIPullRequests(ctx context.Context, baseRepo *repo_model.Repository, prs if err := issueList.LoadAssignees(ctx); err != nil { return nil, err } + if err = issueList.LoadPinOrder(ctx); err != nil { + return nil, err + } reviews, err := prs.LoadReviews(ctx) if err != nil { @@ -368,7 +371,7 @@ func ToAPIPullRequests(ctx context.Context, baseRepo *repo_model.Repository, prs Deadline: apiIssue.Deadline, Created: pr.Issue.CreatedUnix.AsTimePtr(), Updated: pr.Issue.UpdatedUnix.AsTimePtr(), - PinOrder: apiIssue.PinOrder, + PinOrder: util.Iif(apiIssue.PinOrder == -1, 0, apiIssue.PinOrder), AllowMaintainerEdit: pr.AllowMaintainerEdit, diff --git a/services/issue/issue.go b/services/issue/issue.go index 091b7c02d7751..586b6031c8460 100644 --- a/services/issue/issue.go +++ b/services/issue/issue.go @@ -197,13 +197,6 @@ func DeleteIssue(ctx context.Context, doer *user_model.User, gitRepo *git.Reposi } } - // If the Issue is pinned, we should unpin it before deletion to avoid problems with other pinned Issues - if issue.IsPinned() { - if err := issue.Unpin(ctx, doer); err != nil { - return err - } - } - notify_service.DeleteIssue(ctx, doer, issue) return nil @@ -319,6 +312,7 @@ func deleteIssue(ctx context.Context, issue *issues_model.Issue) error { &issues_model.Comment{RefIssueID: issue.ID}, &issues_model.IssueDependency{DependencyID: issue.ID}, &issues_model.Comment{DependentIssueID: issue.ID}, + &issues_model.IssuePin{IssueID: issue.ID}, ); err != nil { return err } diff --git a/services/projects/issue.go b/services/projects/issue.go index 6ca0f168060ad..090d19d2f4700 100644 --- a/services/projects/issue.go +++ b/services/projects/issue.go @@ -11,6 +11,7 @@ import ( issues_model "code.gitea.io/gitea/models/issues" project_model "code.gitea.io/gitea/models/project" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/optional" ) // MoveIssuesOnProjectColumn moves or keeps issues in a column and sorts them inside that column @@ -84,3 +85,123 @@ func MoveIssuesOnProjectColumn(ctx context.Context, doer *user_model.User, colum return nil }) } + +// LoadIssuesFromProject load issues assigned to each project column inside the given project +func LoadIssuesFromProject(ctx context.Context, project *project_model.Project, opts *issues_model.IssuesOptions) (map[int64]issues_model.IssueList, error) { + issueList, err := issues_model.Issues(ctx, opts.Copy(func(o *issues_model.IssuesOptions) { + o.ProjectID = project.ID + o.SortType = "project-column-sorting" + })) + if err != nil { + return nil, err + } + + if err := issueList.LoadComments(ctx); err != nil { + return nil, err + } + + defaultColumn, err := project.MustDefaultColumn(ctx) + if err != nil { + return nil, err + } + + issueColumnMap, err := issues_model.LoadProjectIssueColumnMap(ctx, project.ID, defaultColumn.ID) + if err != nil { + return nil, err + } + + results := make(map[int64]issues_model.IssueList) + for _, issue := range issueList { + projectColumnID, ok := issueColumnMap[issue.ID] + if !ok { + continue + } + if _, ok := results[projectColumnID]; !ok { + results[projectColumnID] = make(issues_model.IssueList, 0) + } + results[projectColumnID] = append(results[projectColumnID], issue) + } + return results, nil +} + +// NumClosedIssues return counter of closed issues assigned to a project +func loadNumClosedIssues(ctx context.Context, p *project_model.Project) error { + cnt, err := db.GetEngine(ctx).Table("project_issue"). + Join("INNER", "issue", "project_issue.issue_id=issue.id"). + Where("project_issue.project_id=? AND issue.is_closed=?", p.ID, true). + Cols("issue_id"). + Count() + if err != nil { + return err + } + p.NumClosedIssues = cnt + return nil +} + +// NumOpenIssues return counter of open issues assigned to a project +func loadNumOpenIssues(ctx context.Context, p *project_model.Project) error { + cnt, err := db.GetEngine(ctx).Table("project_issue"). + Join("INNER", "issue", "project_issue.issue_id=issue.id"). + Where("project_issue.project_id=? AND issue.is_closed=?", p.ID, false). + Cols("issue_id"). + Count() + if err != nil { + return err + } + p.NumOpenIssues = cnt + return nil +} + +func LoadIssueNumbersForProjects(ctx context.Context, projects []*project_model.Project, doer *user_model.User) error { + for _, project := range projects { + if err := LoadIssueNumbersForProject(ctx, project, doer); err != nil { + return err + } + } + return nil +} + +func LoadIssueNumbersForProject(ctx context.Context, project *project_model.Project, doer *user_model.User) error { + // for repository project, just get the numbers + if project.OwnerID == 0 { + if err := loadNumClosedIssues(ctx, project); err != nil { + return err + } + if err := loadNumOpenIssues(ctx, project); err != nil { + return err + } + project.NumIssues = project.NumClosedIssues + project.NumOpenIssues + return nil + } + + if err := project.LoadOwner(ctx); err != nil { + return err + } + + // for user or org projects, we need to check access permissions + opts := issues_model.IssuesOptions{ + ProjectID: project.ID, + Doer: doer, + AllPublic: doer == nil, + Owner: project.Owner, + } + + var err error + project.NumOpenIssues, err = issues_model.CountIssues(ctx, opts.Copy(func(o *issues_model.IssuesOptions) { + o.IsClosed = optional.Some(false) + })) + if err != nil { + return err + } + + project.NumClosedIssues, err = issues_model.CountIssues(ctx, opts.Copy(func(o *issues_model.IssuesOptions) { + o.IsClosed = optional.Some(true) + })) + if err != nil { + return err + } + + project.NumIssues = project.NumClosedIssues + project.NumOpenIssues + + return nil +} diff --git a/services/projects/issue_test.go b/services/projects/issue_test.go new file mode 100644 index 0000000000000..b6f0b1dae11a7 --- /dev/null +++ b/services/projects/issue_test.go @@ -0,0 +1,210 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package project + +import ( + "testing" + + "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" + org_model "code.gitea.io/gitea/models/organization" + project_model "code.gitea.io/gitea/models/project" + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" + user_model "code.gitea.io/gitea/models/user" + + "github.com/stretchr/testify/assert" +) + +func Test_Projects(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + userAdmin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + org3 := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{ID: 3}) + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + + t.Run("User projects", func(t *testing.T) { + pi1 := project_model.ProjectIssue{ + ProjectID: 4, + IssueID: 1, + ProjectColumnID: 4, + } + err := db.Insert(db.DefaultContext, &pi1) + assert.NoError(t, err) + defer func() { + _, err = db.DeleteByID[project_model.ProjectIssue](db.DefaultContext, pi1.ID) + assert.NoError(t, err) + }() + + pi2 := project_model.ProjectIssue{ + ProjectID: 4, + IssueID: 4, + ProjectColumnID: 4, + } + err = db.Insert(db.DefaultContext, &pi2) + assert.NoError(t, err) + defer func() { + _, err = db.DeleteByID[project_model.ProjectIssue](db.DefaultContext, pi2.ID) + assert.NoError(t, err) + }() + + projects, err := db.Find[project_model.Project](db.DefaultContext, project_model.SearchOptions{ + OwnerID: user2.ID, + }) + assert.NoError(t, err) + assert.Len(t, projects, 3) + assert.EqualValues(t, 4, projects[0].ID) + + t.Run("Authenticated user", func(t *testing.T) { + columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + Owner: user2, + Doer: user2, + }) + assert.NoError(t, err) + assert.Len(t, columnIssues, 1) // 4 has 2 issues, 6 will not contains here because 0 issues + assert.Len(t, columnIssues[4], 2) // user2 can visit both issues, one from public repository one from private repository + }) + + t.Run("Anonymous user", func(t *testing.T) { + columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + AllPublic: true, + }) + assert.NoError(t, err) + assert.Len(t, columnIssues, 1) + assert.Len(t, columnIssues[4], 1) // anonymous user can only visit public repo issues + }) + + t.Run("Authenticated user with no permission to the private repo", func(t *testing.T) { + columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + Owner: user2, + Doer: user4, + }) + assert.NoError(t, err) + assert.Len(t, columnIssues, 1) + assert.Len(t, columnIssues[4], 1) // user4 can only visit public repo issues + }) + }) + + t.Run("Org projects", func(t *testing.T) { + project1 := project_model.Project{ + Title: "project in an org", + OwnerID: org3.ID, + Type: project_model.TypeOrganization, + TemplateType: project_model.TemplateTypeBasicKanban, + } + err := project_model.NewProject(db.DefaultContext, &project1) + assert.NoError(t, err) + defer func() { + err := project_model.DeleteProjectByID(db.DefaultContext, project1.ID) + assert.NoError(t, err) + }() + + column1 := project_model.Column{ + Title: "column 1", + ProjectID: project1.ID, + } + err = project_model.NewColumn(db.DefaultContext, &column1) + assert.NoError(t, err) + + column2 := project_model.Column{ + Title: "column 2", + ProjectID: project1.ID, + } + err = project_model.NewColumn(db.DefaultContext, &column2) + assert.NoError(t, err) + + // issue 6 belongs to private repo 3 under org 3 + issue6 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 6}) + err = issues_model.IssueAssignOrRemoveProject(db.DefaultContext, issue6, user2, project1.ID, column1.ID) + assert.NoError(t, err) + + // issue 16 belongs to public repo 16 under org 3 + issue16 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 16}) + err = issues_model.IssueAssignOrRemoveProject(db.DefaultContext, issue16, user2, project1.ID, column1.ID) + assert.NoError(t, err) + + projects, err := db.Find[project_model.Project](db.DefaultContext, project_model.SearchOptions{ + OwnerID: org3.ID, + }) + assert.NoError(t, err) + assert.Len(t, projects, 1) + assert.EqualValues(t, project1.ID, projects[0].ID) + + t.Run("Authenticated user", func(t *testing.T) { + columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + Owner: org3.AsUser(), + Doer: userAdmin, + }) + assert.NoError(t, err) + assert.Len(t, columnIssues, 1) // column1 has 2 issues, 6 will not contains here because 0 issues + assert.Len(t, columnIssues[column1.ID], 2) // user2 can visit both issues, one from public repository one from private repository + }) + + t.Run("Anonymous user", func(t *testing.T) { + columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + AllPublic: true, + }) + assert.NoError(t, err) + assert.Len(t, columnIssues, 1) + assert.Len(t, columnIssues[column1.ID], 1) // anonymous user can only visit public repo issues + }) + + t.Run("Authenticated user with no permission to the private repo", func(t *testing.T) { + columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + Owner: org3.AsUser(), + Doer: user2, + }) + assert.NoError(t, err) + assert.Len(t, columnIssues, 1) + assert.Len(t, columnIssues[column1.ID], 1) // user4 can only visit public repo issues + }) + }) + + t.Run("Repository projects", func(t *testing.T) { + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + + projects, err := db.Find[project_model.Project](db.DefaultContext, project_model.SearchOptions{ + RepoID: repo1.ID, + }) + assert.NoError(t, err) + assert.Len(t, projects, 1) + assert.EqualValues(t, 1, projects[0].ID) + + t.Run("Authenticated user", func(t *testing.T) { + columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + RepoIDs: []int64{repo1.ID}, + Doer: userAdmin, + }) + assert.NoError(t, err) + assert.Len(t, columnIssues, 3) + assert.Len(t, columnIssues[1], 2) + assert.Len(t, columnIssues[2], 1) + assert.Len(t, columnIssues[3], 1) + }) + + t.Run("Anonymous user", func(t *testing.T) { + columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + AllPublic: true, + }) + assert.NoError(t, err) + assert.Len(t, columnIssues, 3) + assert.Len(t, columnIssues[1], 2) + assert.Len(t, columnIssues[2], 1) + assert.Len(t, columnIssues[3], 1) + }) + + t.Run("Authenticated user with no permission to the private repo", func(t *testing.T) { + columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ + RepoIDs: []int64{repo1.ID}, + Doer: user2, + }) + assert.NoError(t, err) + assert.Len(t, columnIssues, 3) + assert.Len(t, columnIssues[1], 2) + assert.Len(t, columnIssues[2], 1) + assert.Len(t, columnIssues[3], 1) + }) + }) +} diff --git a/services/projects/main_test.go b/services/projects/main_test.go new file mode 100644 index 0000000000000..d39c82a140e5e --- /dev/null +++ b/services/projects/main_test.go @@ -0,0 +1,17 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package project + +import ( + "testing" + + "code.gitea.io/gitea/models/unittest" + + _ "code.gitea.io/gitea/models/actions" + _ "code.gitea.io/gitea/models/activities" +) + +func TestMain(m *testing.M) { + unittest.MainTest(m) +} diff --git a/services/repository/delete.go b/services/repository/delete.go index 2166b4dd5c352..fb3fffdca71a0 100644 --- a/services/repository/delete.go +++ b/services/repository/delete.go @@ -158,6 +158,7 @@ func DeleteRepositoryDirectly(ctx context.Context, doer *user_model.User, repoID &actions_model.ActionSchedule{RepoID: repoID}, &actions_model.ActionArtifact{RepoID: repoID}, &actions_model.ActionRunnerToken{RepoID: repoID}, + &issues_model.IssuePin{RepoID: repoID}, ); err != nil { return fmt.Errorf("deleteBeans: %w", err) } diff --git a/services/webhook/notifier.go b/services/webhook/notifier.go index 6c691c21f438e..76d6fd3472c58 100644 --- a/services/webhook/notifier.go +++ b/services/webhook/notifier.go @@ -15,6 +15,7 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" @@ -871,6 +872,11 @@ func (m *webhookNotifier) CreateCommitStatus(ctx context.Context, repo *repo_mod return } + // as a webhook url, target should be an absolute url. But for internal actions target url + // the target url is a url path with no host and port to make it easy to be visited + // from multiple hosts. So we need to convert it to an absolute url here. + target := httplib.MakeAbsoluteURL(ctx, status.TargetURL) + payload := api.CommitStatusPayload{ Context: status.Context, CreatedAt: status.CreatedUnix.AsTime().UTC(), @@ -878,7 +884,7 @@ func (m *webhookNotifier) CreateCommitStatus(ctx context.Context, repo *repo_mod ID: status.ID, SHA: commit.Sha1, State: status.State.String(), - TargetURL: status.TargetURL, + TargetURL: target, Commit: apiCommit, Repo: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeOwner}), diff --git a/templates/projects/list.tmpl b/templates/projects/list.tmpl index 7c75585bf7320..5d40653dc672c 100644 --- a/templates/projects/list.tmpl +++ b/templates/projects/list.tmpl @@ -54,11 +54,11 @@