aboutsummaryrefslogtreecommitdiffstats
path: root/routers/api/v1/repo/issue.go
diff options
context:
space:
mode:
Diffstat (limited to 'routers/api/v1/repo/issue.go')
-rw-r--r--routers/api/v1/repo/issue.go143
1 files changed, 76 insertions, 67 deletions
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index 86dbcee5f7..d4a5872fd1 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
}
@@ -152,7 +152,7 @@ func SearchIssues(ctx *context.APIContext) {
)
{
// find repos user can access (for issue search)
- opts := &repo_model.SearchRepoOptions{
+ opts := repo_model.SearchRepoOptions{
Private: false,
AllPublic: true,
TopicOnly: false,
@@ -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
}
}
@@ -290,10 +290,10 @@ func SearchIssues(ctx *context.APIContext) {
if ctx.IsSigned {
ctxUserID := ctx.Doer.ID
if ctx.FormBool("created") {
- searchOpt.PosterID = optional.Some(ctxUserID)
+ searchOpt.PosterID = strconv.FormatInt(ctxUserID, 10)
}
if ctx.FormBool("assigned") {
- searchOpt.AssigneeID = optional.Some(ctxUserID)
+ searchOpt.AssigneeID = strconv.FormatInt(ctxUserID, 10)
}
if ctx.FormBool("mentioned") {
searchOpt.MentionID = optional.Some(ctxUserID)
@@ -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)
@@ -538,10 +538,10 @@ func ListIssues(ctx *context.APIContext) {
}
if createdByID > 0 {
- searchOpt.PosterID = optional.Some(createdByID)
+ searchOpt.PosterID = strconv.FormatInt(createdByID, 10)
}
if assignedByID > 0 {
- searchOpt.AssigneeID = optional.Some(assignedByID)
+ searchOpt.AssigneeID = strconv.FormatInt(assignedByID, 10)
}
if mentionedByID > 0 {
searchOpt.MentionID = optional.Some(mentionedByID)
@@ -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
}
@@ -895,19 +895,28 @@ func EditIssue(ctx *context.APIContext) {
issue.MilestoneID != *form.Milestone {
oldMilestoneID := issue.MilestoneID
issue.MilestoneID = *form.Milestone
+ if issue.MilestoneID > 0 {
+ issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, *form.Milestone)
+ if err != nil {
+ ctx.APIErrorInternal(err)
+ return
+ }
+ } else {
+ issue.Milestone = nil
+ }
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 +931,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 +972,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 +1028,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 +1051,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
}
}