[go-server] Allow user to specify how errors are handled (#9764)

* Added error.go

* Updated controller to use error

* Fix redeclared func

* Add generated files

* Merge

* Added docs

* Remove variadic

* Regenerate files

* Updated go doc to meet standard

* Updated doc to meet go standard

* Updated
This commit is contained in:
Ween Jiann 2021-07-28 17:19:47 +08:00 committed by GitHub
parent 4c8c576a0f
commit 870ef3a87a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 366 additions and 102 deletions

View File

@ -244,6 +244,7 @@ public class GoServerCodegen extends AbstractGoCodegen {
supportingFiles.add(new SupportingFile("impl.mustache",sourceFolder, "impl.go"));
supportingFiles.add(new SupportingFile("helpers.mustache", sourceFolder, "helpers.go"));
supportingFiles.add(new SupportingFile("api.mustache", sourceFolder, "api.go"));
supportingFiles.add(new SupportingFile("error.mustache", sourceFolder, "error.go"));
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")
.doNotOverwrite());
}

View File

@ -16,14 +16,34 @@ import (
{{/routers}}
)
// A {{classname}}Controller binds http requests to an api service and writes the service results to the http response
// {{classname}}Controller binds http requests to an api service and writes the service results to the http response
type {{classname}}Controller struct {
service {{classname}}Servicer
errorHandler ErrorHandler
}
// {{classname}}Option for how the controller is set up.
type {{classname}}Option func(*{{classname}}Controller)
// With{{classname}}ErrorHandler inject ErrorHandler into controller
func With{{classname}}ErrorHandler(h ErrorHandler) {{classname}}Option {
return func(c *{{classname}}Controller) {
c.errorHandler = h
}
}
// New{{classname}}Controller creates a default api controller
func New{{classname}}Controller(s {{classname}}Servicer) Router {
return &{{classname}}Controller{service: s}
func New{{classname}}Controller(s {{classname}}Servicer, opts ...{{classname}}Option) Router {
controller := &{{classname}}Controller{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all of the api route for the {{classname}}Controller
@ -43,13 +63,13 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
{{#hasFormParams}}
{{#isMultipart}}
if err := r.ParseMultipartForm(32 << 20); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isMultipart}}
{{^isMultipart}}
if err := r.ParseForm(); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isMultipart}}
@ -69,14 +89,14 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
{{#isLong}}
{{paramName}}, err := parseInt64Parameter({{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}, {{required}})
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isLong}}
{{#isInteger}}
{{paramName}}, err := parseInt32Parameter({{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}}, {{required}})
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isInteger}}
@ -89,14 +109,14 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
{{#isLong}}
{{paramName}}, err := parseInt64Parameter(query.Get("{{baseName}}"), {{required}})
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isLong}}
{{#isInteger}}
{{paramName}}, err := parseInt32Parameter(query.Get("{{baseName}}"), {{required}})
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isInteger}}
@ -121,7 +141,7 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
{{paramName}}, err := ReadFormFileToTempFile(r, "{{baseName}}")
{{/isArray}}
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isFile}}
@ -129,7 +149,7 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
{{paramName}}, err := parseInt64ArrayParameter(r.FormValue("{{baseName}}"), ",", {{required}}){{/isArray}}{{^isArray}}
{{paramName}}, err := parseInt64Parameter(r.FormValue("{{baseName}}"), {{required}}){{/isArray}}
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isLong}}
@ -137,7 +157,7 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
{{paramName}}, err := parseInt32ArrayParameter(r.FormValue("{{baseName}}"), ",", {{required}}){{/isArray}}{{^isArray}}
{{paramName}}, err := parseInt32Parameter(r.FormValue("{{baseName}}"), {{required}}){{/isArray}}
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isInteger}}
@ -153,7 +173,7 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
{{#isBodyParam}}
{{paramName}} := &{{dataType}}{}
if err := json.NewDecoder(r.Body).Decode(&{{paramName}}); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
{{/isBodyParam}}
@ -161,7 +181,7 @@ func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Re
result, err := c.service.{{nickname}}(r.Context(){{#allParams}}, {{#isBodyParam}}*{{/isBodyParam}}{{paramName}}{{/allParams}})
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code,{{#addResponseHeaders}} result.Headers,{{/addResponseHeaders}} w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code

View File

@ -0,0 +1,35 @@
{{>partial_header}}
package {{packageName}}
import (
"net/http"
)
// ParsingError indicates that an error has occurred when parsing request parameters
type ParsingError struct {
Err error
}
func (e *ParsingError) Unwrap() error {
return e.Err
}
func (e *ParsingError) Error() string {
return e.Err.Error()
}
// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if
// you would like errors to be handled differently from the DefaultErrorHandler
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse)
// DefaultErrorHandler defines the default logic on how to handle errors from the controller. Any errors from parsing
// request params will return a StatusBadRequest. Otherwise, the error code originating from the servicer will be used.
func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) {
if _, ok := err.(*ParsingError); ok {
// Handle parsing errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest),{{#addResponseHeaders}} map[string][]string{},{{/addResponseHeaders}} w)
} else {
// Handle all other errors
EncodeJSONResponse(err.Error(), &result.Code,{{#addResponseHeaders}} result.Headers,{{/addResponseHeaders}} w)
}
}

View File

@ -9,6 +9,7 @@ go/api_store.go
go/api_store_service.go
go/api_user.go
go/api_user_service.go
go/error.go
go/helpers.go
go/impl.go
go/logger.go

View File

@ -17,14 +17,34 @@ import (
"github.com/gorilla/mux"
)
// A PetApiController binds http requests to an api service and writes the service results to the http response
// PetApiController binds http requests to an api service and writes the service results to the http response
type PetApiController struct {
service PetApiServicer
errorHandler ErrorHandler
}
// PetApiOption for how the controller is set up.
type PetApiOption func(*PetApiController)
// WithPetApiErrorHandler inject ErrorHandler into controller
func WithPetApiErrorHandler(h ErrorHandler) PetApiOption {
return func(c *PetApiController) {
c.errorHandler = h
}
}
// NewPetApiController creates a default api controller
func NewPetApiController(s PetApiServicer) Router {
return &PetApiController{service: s}
func NewPetApiController(s PetApiServicer, opts ...PetApiOption) Router {
controller := &PetApiController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all of the api route for the PetApiController
@ -85,13 +105,13 @@ func (c *PetApiController) Routes() Routes {
func (c *PetApiController) AddPet(w http.ResponseWriter, r *http.Request) {
pet := &Pet{}
if err := json.NewDecoder(r.Body).Decode(&pet); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.AddPet(r.Context(), *pet)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -104,7 +124,7 @@ func (c *PetApiController) DeletePet(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
petId, err := parseInt64Parameter(params["petId"], true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
@ -112,7 +132,7 @@ func (c *PetApiController) DeletePet(w http.ResponseWriter, r *http.Request) {
result, err := c.service.DeletePet(r.Context(), petId, apiKey)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -127,7 +147,7 @@ func (c *PetApiController) FindPetsByStatus(w http.ResponseWriter, r *http.Reque
result, err := c.service.FindPetsByStatus(r.Context(), status)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -142,7 +162,7 @@ func (c *PetApiController) FindPetsByTags(w http.ResponseWriter, r *http.Request
result, err := c.service.FindPetsByTags(r.Context(), tags)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -155,14 +175,14 @@ func (c *PetApiController) GetPetById(w http.ResponseWriter, r *http.Request) {
params := mux.Vars(r)
petId, err := parseInt64Parameter(params["petId"], true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.GetPetById(r.Context(), petId)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -174,13 +194,13 @@ func (c *PetApiController) GetPetById(w http.ResponseWriter, r *http.Request) {
func (c *PetApiController) UpdatePet(w http.ResponseWriter, r *http.Request) {
pet := &Pet{}
if err := json.NewDecoder(r.Body).Decode(&pet); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UpdatePet(r.Context(), *pet)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -191,13 +211,13 @@ func (c *PetApiController) UpdatePet(w http.ResponseWriter, r *http.Request) {
// UpdatePetWithForm - Updates a pet in the store with form data
func (c *PetApiController) UpdatePetWithForm(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
params := mux.Vars(r)
petId, err := parseInt64Parameter(params["petId"], true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
@ -206,7 +226,7 @@ func (c *PetApiController) UpdatePetWithForm(w http.ResponseWriter, r *http.Requ
result, err := c.service.UpdatePetWithForm(r.Context(), petId, name, status)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -217,13 +237,13 @@ func (c *PetApiController) UpdatePetWithForm(w http.ResponseWriter, r *http.Requ
// UploadFile - uploads an image
func (c *PetApiController) UploadFile(w http.ResponseWriter, r *http.Request) {
if err := r.ParseMultipartForm(32 << 20); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
params := mux.Vars(r)
petId, err := parseInt64Parameter(params["petId"], true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
@ -231,13 +251,13 @@ func (c *PetApiController) UploadFile(w http.ResponseWriter, r *http.Request) {
file, err := ReadFormFileToTempFile(r, "file")
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UploadFile(r.Context(), petId, additionalMetadata, file)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code

View File

@ -17,14 +17,34 @@ import (
"github.com/gorilla/mux"
)
// A StoreApiController binds http requests to an api service and writes the service results to the http response
// StoreApiController binds http requests to an api service and writes the service results to the http response
type StoreApiController struct {
service StoreApiServicer
errorHandler ErrorHandler
}
// StoreApiOption for how the controller is set up.
type StoreApiOption func(*StoreApiController)
// WithStoreApiErrorHandler inject ErrorHandler into controller
func WithStoreApiErrorHandler(h ErrorHandler) StoreApiOption {
return func(c *StoreApiController) {
c.errorHandler = h
}
}
// NewStoreApiController creates a default api controller
func NewStoreApiController(s StoreApiServicer) Router {
return &StoreApiController{service: s}
func NewStoreApiController(s StoreApiServicer, opts ...StoreApiOption) Router {
controller := &StoreApiController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all of the api route for the StoreApiController
@ -65,7 +85,7 @@ func (c *StoreApiController) DeleteOrder(w http.ResponseWriter, r *http.Request)
result, err := c.service.DeleteOrder(r.Context(), orderId)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -78,7 +98,7 @@ func (c *StoreApiController) GetInventory(w http.ResponseWriter, r *http.Request
result, err := c.service.GetInventory(r.Context())
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -91,14 +111,14 @@ func (c *StoreApiController) GetOrderById(w http.ResponseWriter, r *http.Request
params := mux.Vars(r)
orderId, err := parseInt64Parameter(params["orderId"], true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.GetOrderById(r.Context(), orderId)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -110,13 +130,13 @@ func (c *StoreApiController) GetOrderById(w http.ResponseWriter, r *http.Request
func (c *StoreApiController) PlaceOrder(w http.ResponseWriter, r *http.Request) {
order := &Order{}
if err := json.NewDecoder(r.Body).Decode(&order); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.PlaceOrder(r.Context(), *order)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code

View File

@ -17,14 +17,34 @@ import (
"github.com/gorilla/mux"
)
// A UserApiController binds http requests to an api service and writes the service results to the http response
// UserApiController binds http requests to an api service and writes the service results to the http response
type UserApiController struct {
service UserApiServicer
errorHandler ErrorHandler
}
// UserApiOption for how the controller is set up.
type UserApiOption func(*UserApiController)
// WithUserApiErrorHandler inject ErrorHandler into controller
func WithUserApiErrorHandler(h ErrorHandler) UserApiOption {
return func(c *UserApiController) {
c.errorHandler = h
}
}
// NewUserApiController creates a default api controller
func NewUserApiController(s UserApiServicer) Router {
return &UserApiController{service: s}
func NewUserApiController(s UserApiServicer, opts ...UserApiOption) Router {
controller := &UserApiController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all of the api route for the UserApiController
@ -85,13 +105,13 @@ func (c *UserApiController) Routes() Routes {
func (c *UserApiController) CreateUser(w http.ResponseWriter, r *http.Request) {
user := &User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUser(r.Context(), *user)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -103,13 +123,13 @@ func (c *UserApiController) CreateUser(w http.ResponseWriter, r *http.Request) {
func (c *UserApiController) CreateUsersWithArrayInput(w http.ResponseWriter, r *http.Request) {
user := &[]User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUsersWithArrayInput(r.Context(), *user)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -121,13 +141,13 @@ func (c *UserApiController) CreateUsersWithArrayInput(w http.ResponseWriter, r *
func (c *UserApiController) CreateUsersWithListInput(w http.ResponseWriter, r *http.Request) {
user := &[]User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUsersWithListInput(r.Context(), *user)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -143,7 +163,7 @@ func (c *UserApiController) DeleteUser(w http.ResponseWriter, r *http.Request) {
result, err := c.service.DeleteUser(r.Context(), username)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -159,7 +179,7 @@ func (c *UserApiController) GetUserByName(w http.ResponseWriter, r *http.Request
result, err := c.service.GetUserByName(r.Context(), username)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -175,7 +195,7 @@ func (c *UserApiController) LoginUser(w http.ResponseWriter, r *http.Request) {
result, err := c.service.LoginUser(r.Context(), username, password)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -188,7 +208,7 @@ func (c *UserApiController) LogoutUser(w http.ResponseWriter, r *http.Request) {
result, err := c.service.LogoutUser(r.Context())
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -203,13 +223,13 @@ func (c *UserApiController) UpdateUser(w http.ResponseWriter, r *http.Request) {
user := &User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UpdateUser(r.Context(), username, *user)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code

View File

@ -0,0 +1,43 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"net/http"
)
// ParsingError indicates that an error has occurred when parsing request parameters
type ParsingError struct {
Err error
}
func (e *ParsingError) Unwrap() error {
return e.Err
}
func (e *ParsingError) Error() string {
return e.Err.Error()
}
// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if
// you would like errors to be handled differently from the DefaultErrorHandler
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse)
// DefaultErrorHandler defines the default logic on how to handle errors from the controller. Any errors from parsing
// request params will return a StatusBadRequest. Otherwise, the error code originating from the servicer will be used.
func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) {
if _, ok := err.(*ParsingError); ok {
// Handle parsing errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest), map[string][]string{}, w)
} else {
// Handle all other errors
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
}
}

View File

@ -9,6 +9,7 @@ go/api_store.go
go/api_store_service.go
go/api_user.go
go/api_user_service.go
go/error.go
go/helpers.go
go/impl.go
go/logger.go

View File

@ -17,14 +17,34 @@ import (
"github.com/go-chi/chi/v5"
)
// A PetApiController binds http requests to an api service and writes the service results to the http response
// PetApiController binds http requests to an api service and writes the service results to the http response
type PetApiController struct {
service PetApiServicer
errorHandler ErrorHandler
}
// PetApiOption for how the controller is set up.
type PetApiOption func(*PetApiController)
// WithPetApiErrorHandler inject ErrorHandler into controller
func WithPetApiErrorHandler(h ErrorHandler) PetApiOption {
return func(c *PetApiController) {
c.errorHandler = h
}
}
// NewPetApiController creates a default api controller
func NewPetApiController(s PetApiServicer) Router {
return &PetApiController{service: s}
func NewPetApiController(s PetApiServicer, opts ...PetApiOption) Router {
controller := &PetApiController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all of the api route for the PetApiController
@ -85,13 +105,13 @@ func (c *PetApiController) Routes() Routes {
func (c *PetApiController) AddPet(w http.ResponseWriter, r *http.Request) {
pet := &Pet{}
if err := json.NewDecoder(r.Body).Decode(&pet); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.AddPet(r.Context(), *pet)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -103,7 +123,7 @@ func (c *PetApiController) AddPet(w http.ResponseWriter, r *http.Request) {
func (c *PetApiController) DeletePet(w http.ResponseWriter, r *http.Request) {
petId, err := parseInt64Parameter(chi.URLParam(r, "petId"), true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
@ -111,7 +131,7 @@ func (c *PetApiController) DeletePet(w http.ResponseWriter, r *http.Request) {
result, err := c.service.DeletePet(r.Context(), petId, apiKey)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -126,7 +146,7 @@ func (c *PetApiController) FindPetsByStatus(w http.ResponseWriter, r *http.Reque
result, err := c.service.FindPetsByStatus(r.Context(), status)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -141,7 +161,7 @@ func (c *PetApiController) FindPetsByTags(w http.ResponseWriter, r *http.Request
result, err := c.service.FindPetsByTags(r.Context(), tags)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -153,14 +173,14 @@ func (c *PetApiController) FindPetsByTags(w http.ResponseWriter, r *http.Request
func (c *PetApiController) GetPetById(w http.ResponseWriter, r *http.Request) {
petId, err := parseInt64Parameter(chi.URLParam(r, "petId"), true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.GetPetById(r.Context(), petId)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -172,13 +192,13 @@ func (c *PetApiController) GetPetById(w http.ResponseWriter, r *http.Request) {
func (c *PetApiController) UpdatePet(w http.ResponseWriter, r *http.Request) {
pet := &Pet{}
if err := json.NewDecoder(r.Body).Decode(&pet); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UpdatePet(r.Context(), *pet)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -189,12 +209,12 @@ func (c *PetApiController) UpdatePet(w http.ResponseWriter, r *http.Request) {
// UpdatePetWithForm - Updates a pet in the store with form data
func (c *PetApiController) UpdatePetWithForm(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
petId, err := parseInt64Parameter(chi.URLParam(r, "petId"), true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
@ -203,7 +223,7 @@ func (c *PetApiController) UpdatePetWithForm(w http.ResponseWriter, r *http.Requ
result, err := c.service.UpdatePetWithForm(r.Context(), petId, name, status)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -214,12 +234,12 @@ func (c *PetApiController) UpdatePetWithForm(w http.ResponseWriter, r *http.Requ
// UploadFile - uploads an image
func (c *PetApiController) UploadFile(w http.ResponseWriter, r *http.Request) {
if err := r.ParseMultipartForm(32 << 20); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
petId, err := parseInt64Parameter(chi.URLParam(r, "petId"), true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
@ -227,13 +247,13 @@ func (c *PetApiController) UploadFile(w http.ResponseWriter, r *http.Request) {
file, err := ReadFormFileToTempFile(r, "file")
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UploadFile(r.Context(), petId, additionalMetadata, file)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code

View File

@ -17,14 +17,34 @@ import (
"github.com/go-chi/chi/v5"
)
// A StoreApiController binds http requests to an api service and writes the service results to the http response
// StoreApiController binds http requests to an api service and writes the service results to the http response
type StoreApiController struct {
service StoreApiServicer
errorHandler ErrorHandler
}
// StoreApiOption for how the controller is set up.
type StoreApiOption func(*StoreApiController)
// WithStoreApiErrorHandler inject ErrorHandler into controller
func WithStoreApiErrorHandler(h ErrorHandler) StoreApiOption {
return func(c *StoreApiController) {
c.errorHandler = h
}
}
// NewStoreApiController creates a default api controller
func NewStoreApiController(s StoreApiServicer) Router {
return &StoreApiController{service: s}
func NewStoreApiController(s StoreApiServicer, opts ...StoreApiOption) Router {
controller := &StoreApiController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all of the api route for the StoreApiController
@ -64,7 +84,7 @@ func (c *StoreApiController) DeleteOrder(w http.ResponseWriter, r *http.Request)
result, err := c.service.DeleteOrder(r.Context(), orderId)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -77,7 +97,7 @@ func (c *StoreApiController) GetInventory(w http.ResponseWriter, r *http.Request
result, err := c.service.GetInventory(r.Context())
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -89,14 +109,14 @@ func (c *StoreApiController) GetInventory(w http.ResponseWriter, r *http.Request
func (c *StoreApiController) GetOrderById(w http.ResponseWriter, r *http.Request) {
orderId, err := parseInt64Parameter(chi.URLParam(r, "orderId"), true)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.GetOrderById(r.Context(), orderId)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -108,13 +128,13 @@ func (c *StoreApiController) GetOrderById(w http.ResponseWriter, r *http.Request
func (c *StoreApiController) PlaceOrder(w http.ResponseWriter, r *http.Request) {
order := &Order{}
if err := json.NewDecoder(r.Body).Decode(&order); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.PlaceOrder(r.Context(), *order)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code

View File

@ -17,14 +17,34 @@ import (
"github.com/go-chi/chi/v5"
)
// A UserApiController binds http requests to an api service and writes the service results to the http response
// UserApiController binds http requests to an api service and writes the service results to the http response
type UserApiController struct {
service UserApiServicer
errorHandler ErrorHandler
}
// UserApiOption for how the controller is set up.
type UserApiOption func(*UserApiController)
// WithUserApiErrorHandler inject ErrorHandler into controller
func WithUserApiErrorHandler(h ErrorHandler) UserApiOption {
return func(c *UserApiController) {
c.errorHandler = h
}
}
// NewUserApiController creates a default api controller
func NewUserApiController(s UserApiServicer) Router {
return &UserApiController{service: s}
func NewUserApiController(s UserApiServicer, opts ...UserApiOption) Router {
controller := &UserApiController{
service: s,
errorHandler: DefaultErrorHandler,
}
for _, opt := range opts {
opt(controller)
}
return controller
}
// Routes returns all of the api route for the UserApiController
@ -85,13 +105,13 @@ func (c *UserApiController) Routes() Routes {
func (c *UserApiController) CreateUser(w http.ResponseWriter, r *http.Request) {
user := &User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUser(r.Context(), *user)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -103,13 +123,13 @@ func (c *UserApiController) CreateUser(w http.ResponseWriter, r *http.Request) {
func (c *UserApiController) CreateUsersWithArrayInput(w http.ResponseWriter, r *http.Request) {
user := &[]User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUsersWithArrayInput(r.Context(), *user)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -121,13 +141,13 @@ func (c *UserApiController) CreateUsersWithArrayInput(w http.ResponseWriter, r *
func (c *UserApiController) CreateUsersWithListInput(w http.ResponseWriter, r *http.Request) {
user := &[]User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.CreateUsersWithListInput(r.Context(), *user)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -142,7 +162,7 @@ func (c *UserApiController) DeleteUser(w http.ResponseWriter, r *http.Request) {
result, err := c.service.DeleteUser(r.Context(), username)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -157,7 +177,7 @@ func (c *UserApiController) GetUserByName(w http.ResponseWriter, r *http.Request
result, err := c.service.GetUserByName(r.Context(), username)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -173,7 +193,7 @@ func (c *UserApiController) LoginUser(w http.ResponseWriter, r *http.Request) {
result, err := c.service.LoginUser(r.Context(), username, password)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -186,7 +206,7 @@ func (c *UserApiController) LogoutUser(w http.ResponseWriter, r *http.Request) {
result, err := c.service.LogoutUser(r.Context())
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code
@ -200,13 +220,13 @@ func (c *UserApiController) UpdateUser(w http.ResponseWriter, r *http.Request) {
user := &User{}
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
w.WriteHeader(http.StatusBadRequest)
c.errorHandler(w, r, &ParsingError{Err: err}, nil)
return
}
result, err := c.service.UpdateUser(r.Context(), username, *user)
// If an error occurred, encode the error with the status code
if err != nil {
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
c.errorHandler(w, r, err, &result)
return
}
// If no error, encode the body and the result code

View File

@ -0,0 +1,43 @@
/*
* OpenAPI Petstore
*
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
*
* API version: 1.0.0
* Generated by: OpenAPI Generator (https://openapi-generator.tech)
*/
package petstoreserver
import (
"net/http"
)
// ParsingError indicates that an error has occurred when parsing request parameters
type ParsingError struct {
Err error
}
func (e *ParsingError) Unwrap() error {
return e.Err
}
func (e *ParsingError) Error() string {
return e.Err.Error()
}
// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if
// you would like errors to be handled differently from the DefaultErrorHandler
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse)
// DefaultErrorHandler defines the default logic on how to handle errors from the controller. Any errors from parsing
// request params will return a StatusBadRequest. Otherwise, the error code originating from the servicer will be used.
func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) {
if _, ok := err.(*ParsingError); ok {
// Handle parsing errors
EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest), map[string][]string{}, w)
} else {
// Handle all other errors
EncodeJSONResponse(err.Error(), &result.Code, result.Headers, w)
}
}