Swagger info corrections (#9441)

* use numbers and not http.Status___ enum

* fix test

* add many missing swagger responses

* code format

* Deletion Sould return 204 ...

* error handling improvements

* if special error type ... then add it to swagger too

* one smal nit

* invalidTopicsError is []string

* valid swagger specification 2.0
 - if you add responses swagger can tell you if you do it right 👍

* use ctx.InternalServerError

* Revert "use numbers and not http.Status___ enum"

This reverts commit b1ff386e2418ed6a7f183e756b13277d701278ef.

* use http.Status* enum everywhere
This commit is contained in:
6543 2019-12-20 18:07:12 +01:00 committed by Lauris BH
parent 050a8af424
commit 2848c5eb8f
52 changed files with 1262 additions and 648 deletions

View file

@ -54,6 +54,7 @@ func SearchIssues(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/IssueList"
var isClosed util.OptionalBool
switch ctx.Query("state") {
case "closed":
@ -81,7 +82,7 @@ func SearchIssues(ctx *context.APIContext) {
OrderBy: models.SearchOrderByRecentUpdated,
})
if err != nil {
ctx.Error(500, "SearchRepositoryByName", err)
ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err)
return
}
@ -119,7 +120,7 @@ func SearchIssues(ctx *context.APIContext) {
if splitted := strings.Split(labels, ","); labels != "" && len(splitted) > 0 {
labelIDs, err = models.GetLabelIDsInReposByNames(repoIDs, splitted)
if err != nil {
ctx.Error(500, "GetLabelIDsInRepoByNames", err)
ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err)
return
}
}
@ -140,7 +141,7 @@ func SearchIssues(ctx *context.APIContext) {
}
if err != nil {
ctx.Error(500, "Issues", err)
ctx.Error(http.StatusInternalServerError, "Issues", err)
return
}
@ -150,7 +151,7 @@ func SearchIssues(ctx *context.APIContext) {
}
ctx.SetLinkHeader(issueCount, setting.UI.IssuePagingNum)
ctx.JSON(200, &apiIssues)
ctx.JSON(http.StatusOK, &apiIssues)
}
// ListIssues list the issues of a repository
@ -190,6 +191,7 @@ func ListIssues(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/IssueList"
var isClosed util.OptionalBool
switch ctx.Query("state") {
case "closed":
@ -216,7 +218,7 @@ func ListIssues(ctx *context.APIContext) {
if splitted := strings.Split(ctx.Query("labels"), ","); len(splitted) > 0 {
labelIDs, err = models.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, splitted)
if err != nil {
ctx.Error(500, "GetLabelIDsInRepoByNames", err)
ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err)
return
}
}
@ -235,7 +237,7 @@ func ListIssues(ctx *context.APIContext) {
}
if err != nil {
ctx.Error(500, "Issues", err)
ctx.Error(http.StatusInternalServerError, "Issues", err)
return
}
@ -245,7 +247,7 @@ func ListIssues(ctx *context.APIContext) {
}
ctx.SetLinkHeader(ctx.Repo.Repository.NumIssues, setting.UI.IssuePagingNum)
ctx.JSON(200, &apiIssues)
ctx.JSON(http.StatusOK, &apiIssues)
}
// GetIssue get an issue of a repository
@ -275,16 +277,19 @@ func GetIssue(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/Issue"
// "404":
// "$ref": "#/responses/notFound"
issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
if err != nil {
if models.IsErrIssueNotExist(err) {
ctx.NotFound()
} else {
ctx.Error(500, "GetIssueByIndex", err)
ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err)
}
return
}
ctx.JSON(200, issue.APIFormat())
ctx.JSON(http.StatusOK, issue.APIFormat())
}
// CreateIssue create an issue of a repository
@ -314,6 +319,12 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
// responses:
// "201":
// "$ref": "#/responses/Issue"
// "403":
// "$ref": "#/responses/forbidden"
// "412":
// "$ref": "#/responses/error"
// "422":
// "$ref": "#/responses/validationError"
var deadlineUnix timeutil.TimeStamp
if form.Deadline != nil && ctx.Repo.CanWrite(models.UnitTypeIssues) {
@ -337,9 +348,9 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
assigneeIDs, err = models.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees)
if err != nil {
if models.IsErrUserNotExist(err) {
ctx.Error(422, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err))
ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err))
} else {
ctx.Error(500, "AddAssigneeByName", err)
ctx.Error(http.StatusInternalServerError, "AddAssigneeByName", err)
}
return
}
@ -348,17 +359,17 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
for _, aID := range assigneeIDs {
assignee, err := models.GetUserByID(aID)
if err != nil {
ctx.Error(500, "GetUserByID", err)
ctx.Error(http.StatusInternalServerError, "GetUserByID", err)
return
}
valid, err := models.CanBeAssigned(assignee, ctx.Repo.Repository, false)
if err != nil {
ctx.Error(500, "canBeAssigned", err)
ctx.Error(http.StatusInternalServerError, "canBeAssigned", err)
return
}
if !valid {
ctx.Error(422, "canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name})
ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name})
return
}
}
@ -369,10 +380,10 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
if err := issue_service.NewIssue(ctx.Repo.Repository, issue, form.Labels, nil, assigneeIDs); err != nil {
if models.IsErrUserDoesNotHaveAccessToRepo(err) {
ctx.Error(400, "UserDoesNotHaveAccessToRepo", err)
ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err)
return
}
ctx.Error(500, "NewIssue", err)
ctx.Error(http.StatusInternalServerError, "NewIssue", err)
return
}
@ -382,7 +393,7 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies")
return
}
ctx.Error(500, "ChangeStatus", err)
ctx.Error(http.StatusInternalServerError, "ChangeStatus", err)
return
}
}
@ -390,10 +401,10 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
// Refetch from database to assign some automatic values
issue, err = models.GetIssueByID(issue.ID)
if err != nil {
ctx.Error(500, "GetIssueByID", err)
ctx.Error(http.StatusInternalServerError, "GetIssueByID", err)
return
}
ctx.JSON(201, issue.APIFormat())
ctx.JSON(http.StatusCreated, issue.APIFormat())
}
// EditIssue modify an issue of a repository
@ -429,12 +440,19 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
// responses:
// "201":
// "$ref": "#/responses/Issue"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "412":
// "$ref": "#/responses/error"
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
if err != nil {
if models.IsErrIssueNotExist(err) {
ctx.NotFound()
} else {
ctx.Error(500, "GetIssueByIndex", err)
ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err)
}
return
}
@ -442,12 +460,12 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
err = issue.LoadAttributes()
if err != nil {
ctx.Error(500, "LoadAttributes", err)
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err)
return
}
if !issue.IsPoster(ctx.User.ID) && !ctx.Repo.CanWrite(models.UnitTypeIssues) {
ctx.Status(403)
ctx.Status(http.StatusForbidden)
return
}
@ -469,7 +487,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
}
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
ctx.Error(500, "UpdateIssueDeadline", err)
ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err)
return
}
issue.DeadlineUnix = deadlineUnix
@ -491,7 +509,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
err = issue_service.UpdateAssignees(issue, oneAssignee, form.Assignees, ctx.User)
if err != nil {
ctx.Error(500, "UpdateAssignees", err)
ctx.Error(http.StatusInternalServerError, "UpdateAssignees", err)
return
}
}
@ -501,13 +519,13 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
oldMilestoneID := issue.MilestoneID
issue.MilestoneID = *form.Milestone
if err = issue_service.ChangeMilestoneAssign(issue, ctx.User, oldMilestoneID); err != nil {
ctx.Error(500, "ChangeMilestoneAssign", err)
ctx.Error(http.StatusInternalServerError, "ChangeMilestoneAssign", err)
return
}
}
if err = models.UpdateIssue(issue); err != nil {
ctx.Error(500, "UpdateIssue", err)
ctx.Error(http.StatusInternalServerError, "UpdateIssue", err)
return
}
if form.State != nil {
@ -516,7 +534,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies")
return
}
ctx.Error(500, "ChangeStatus", err)
ctx.Error(http.StatusInternalServerError, "ChangeStatus", err)
return
}
}
@ -524,10 +542,10 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
// Refetch from database to assign some automatic values
issue, err = models.GetIssueByID(issue.ID)
if err != nil {
ctx.Error(500, "GetIssueByID", err)
ctx.Error(http.StatusInternalServerError, "GetIssueByID", err)
return
}
ctx.JSON(201, issue.APIFormat())
ctx.JSON(http.StatusCreated, issue.APIFormat())
}
// UpdateIssueDeadline updates an issue deadline
@ -564,22 +582,22 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) {
// "201":
// "$ref": "#/responses/IssueDeadline"
// "403":
// description: Not repo writer
// "$ref": "#/responses/forbidden"
// "404":
// description: Issue not found
// "$ref": "#/responses/notFound"
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
if err != nil {
if models.IsErrIssueNotExist(err) {
ctx.NotFound()
} else {
ctx.Error(500, "GetIssueByIndex", err)
ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err)
}
return
}
if !ctx.Repo.CanWrite(models.UnitTypeIssues) {
ctx.Status(403)
ctx.Error(http.StatusForbidden, "", "Not repo writer")
return
}
@ -592,9 +610,9 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) {
}
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
ctx.Error(500, "UpdateIssueDeadline", err)
ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err)
return
}
ctx.JSON(201, api.IssueDeadline{Deadline: &deadline})
ctx.JSON(http.StatusCreated, api.IssueDeadline{Deadline: &deadline})
}