From acd7e57295e3cd91a6a9ce524fd87c5e4b43b590 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Mon, 7 Oct 2024 18:36:07 +0200 Subject: [PATCH] fix: correct documentation for non 200 responses in swagger (cherry picked from commit fcc3dd228de8d22bd98f9dae995d95f10c3635ae) --- services/context/api.go | 70 ++++++++++++----- templates/swagger/v1_json.tmpl | 133 +++++++++++++++++++++++---------- 2 files changed, 146 insertions(+), 57 deletions(-) diff --git a/services/context/api.go b/services/context/api.go index 52d11f5f6a..c560994258 100644 --- a/services/context/api.go +++ b/services/context/api.go @@ -59,40 +59,69 @@ func init() { // if we need to indicate some errors, we should introduce some new fields like ErrorCode or ErrorType // * url: the swagger document URL +type APIError struct { + Message string `json:"message"` + URL string `json:"url"` +} + // APIError is error format response // swagger:response error -type APIError struct { +type swaggerAPIError struct { + // in:body + Body APIError `json:"body"` +} + +type APIValidationError struct { Message string `json:"message"` URL string `json:"url"` } // APIValidationError is error format response related to input validation // swagger:response validationError -type APIValidationError struct { - Message string `json:"message"` - URL string `json:"url"` +type swaggerAPIValidationError struct { + // in:body + Body APIValidationError `json:"body"` +} + +type APIInvalidTopicsError struct { + Message string `json:"message"` + InvalidTopics []string `json:"invalidTopics"` } // APIInvalidTopicsError is error format response to invalid topics // swagger:response invalidTopicsError -type APIInvalidTopicsError struct { - Message string `json:"message"` - InvalidTopics []string `json:"invalidTopics"` +type swaggerAPIInvalidTopicsError struct { + // in:body + Body APIInvalidTopicsError `json:"body"` } // APIEmpty is an empty response // swagger:response empty type APIEmpty struct{} -// APIForbiddenError is a forbidden error response -// swagger:response forbidden type APIForbiddenError struct { APIError } -// APINotFound is a not found empty response +// APIForbiddenError is a forbidden error response +// swagger:response forbidden +type swaggerAPIForbiddenError struct { + // in:body + Body APIForbiddenError `json:"body"` +} + +type APINotFound struct { + Message string `json:"message"` + URL string `json:"url"` + Errors []string `json:"errors"` +} + +// APINotFound is a not found error response // swagger:response notFound -type APINotFound struct{} +type swaggerAPINotFound struct { + // in:body + Body APINotFound `json:"body"` +} // APIConflict is a conflict empty response // swagger:response conflict @@ -106,12 +135,17 @@ type APIRedirect struct{} // swagger:response string type APIString string -// APIRepoArchivedError is an error that is raised when an archived repo should be modified -// swagger:response repoArchivedError type APIRepoArchivedError struct { APIError } +// APIRepoArchivedError is an error that is raised when an archived repo should be modified +// swagger:response repoArchivedError +type swaggerAPIRepoArchivedError struct { + // in:body + Body APIRepoArchivedError `json:"body"` +} + // ServerError responds with error message, status is 500 func (ctx *APIContext) ServerError(title string, err error) { ctx.Error(http.StatusInternalServerError, title, err) @@ -252,7 +286,7 @@ func APIContexter() func(http.Handler) http.Handler { // String will replace message, errors will be added to a slice func (ctx *APIContext) NotFound(objs ...any) { message := ctx.Locale.TrString("error.not_found") - var errors []string + errors := make([]string, 0) for _, obj := range objs { // Ignore nil if obj == nil { @@ -266,10 +300,10 @@ func (ctx *APIContext) NotFound(objs ...any) { } } - ctx.JSON(http.StatusNotFound, map[string]any{ - "message": message, - "url": setting.API.SwaggerURL, - "errors": errors, + ctx.JSON(http.StatusNotFound, APINotFound{ + Message: message, + URL: setting.API.SwaggerURL, + Errors: errors, }) } diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 8c4e7eaf8b..d47f965286 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -19708,6 +19708,86 @@ }, "x-go-package": "code.gitea.io/gitea/modules/structs" }, + "APIForbiddenError": { + "type": "object", + "properties": { + "message": { + "type": "string", + "x-go-name": "Message" + }, + "url": { + "type": "string", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/services/context" + }, + "APIInvalidTopicsError": { + "type": "object", + "properties": { + "invalidTopics": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "InvalidTopics" + }, + "message": { + "type": "string", + "x-go-name": "Message" + } + }, + "x-go-package": "code.gitea.io/gitea/services/context" + }, + "APINotFound": { + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Errors" + }, + "message": { + "type": "string", + "x-go-name": "Message" + }, + "url": { + "type": "string", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/services/context" + }, + "APIRepoArchivedError": { + "type": "object", + "properties": { + "message": { + "type": "string", + "x-go-name": "Message" + }, + "url": { + "type": "string", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/services/context" + }, + "APIValidationError": { + "type": "object", + "properties": { + "message": { + "type": "string", + "x-go-name": "Message" + }, + "url": { + "type": "string", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/services/context" + }, "AccessToken": { "type": "object", "title": "AccessToken represents an API access token.", @@ -28202,42 +28282,27 @@ }, "error": { "description": "APIError is error format response", - "headers": { - "message": { - "type": "string" - }, - "url": { - "type": "string" - } + "schema": { + "$ref": "#/definitions/APIError" } }, "forbidden": { "description": "APIForbiddenError is a forbidden error response", - "headers": { - "message": { - "type": "string" - }, - "url": { - "type": "string" - } + "schema": { + "$ref": "#/definitions/APIForbiddenError" } }, "invalidTopicsError": { "description": "APIInvalidTopicsError is error format response to invalid topics", - "headers": { - "invalidTopics": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } + "schema": { + "$ref": "#/definitions/APIInvalidTopicsError" } }, "notFound": { - "description": "APINotFound is a not found empty response" + "description": "APINotFound is a not found error response", + "schema": { + "$ref": "#/definitions/APINotFound" + } }, "parameterBodies": { "description": "parameterBodies", @@ -28265,13 +28330,8 @@ }, "repoArchivedError": { "description": "APIRepoArchivedError is an error that is raised when an archived repo should be modified", - "headers": { - "message": { - "type": "string" - }, - "url": { - "type": "string" - } + "schema": { + "$ref": "#/definitions/APIRepoArchivedError" } }, "string": { @@ -28282,13 +28342,8 @@ }, "validationError": { "description": "APIValidationError is error format response related to input validation", - "headers": { - "message": { - "type": "string" - }, - "url": { - "type": "string" - } + "schema": { + "$ref": "#/definitions/APIValidationError" } } },