Skip to content

fix: allow response error handler to set status code #1963

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

sean-cunniffe
Copy link

@sean-cunniffe sean-cunniffe commented May 4, 2025

As mentioned in #1964

Version: 2.4.1

Issue: Status code is set to 200 before marshalling data into body inside visit functions, so when an error occurs marshalling the ResponseErrorHandlerFunc cannot set the status code.

Reproduce:

openapi: 3.0.1
info:
  title: error-handler-example
  version: 1.0.0
paths:
  /api/example:
    post:
      operationId: exampleHandler
      responses:
        200:
          description: example
          content:
            application/json:
              schema:
                type: object
                properties:
                  example:
                    type: string
                    format: email
package: api
generate:
  gorilla-server: true
  strict-server: true
  models: true
output: generated/gen.go
package main

import (
	"context"
	"net/http"

	api "example.go/generated"
	openapi_types "github.com/oapi-codegen/runtime/types"
)

type ExampleHandler struct {
}

func main() {
	e := &ExampleHandler{}
	h := api.NewStrictHandlerWithOptions(e, nil, api.StrictHTTPServerOptions{
		ResponseErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) {
			w.WriteHeader(500)
		},
	})
	handler := api.Handler(h)
	err := http.ListenAndServe(":8080", handler)
	panic(err)
}

func (*ExampleHandler) ExampleHandler(ctx context.Context,
	request api.ExampleHandlerRequestObject) (api.ExampleHandlerResponseObject, error) {
	email := openapi_types.Email("invalid email")
	return api.ExampleHandler200JSONResponse{
		Example: &email,
	}, nil
}

Generated visit function

func (response ExampleHandler200JSONResponse) VisitExampleHandlerResponse(w http.ResponseWriter) error {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)

	return json.NewEncoder(w).Encode(response)
}

Proposed changes would have the output

func (response ExampleHandler200JSONResponse) VisitExampleHandlerResponse(w http.ResponseWriter) error {
	if err := json.NewEncoder(w).Encode(response); err != nil {
		return err
	}
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(200)
	return nil
}

change the order the visit response body function sets the status code
and content type so if an error occurs during json marshalling the
response error handler can set the status code
@sean-cunniffe sean-cunniffe requested a review from a team as a code owner May 4, 2025 02:46
@jamietanna jamietanna added server:strict bug Something isn't working labels May 4, 2025
@jamietanna jamietanna added this to the v2.5.0 milestone May 4, 2025
@jamietanna
Copy link
Member

Thanks for reporting + raising a suggested fix! Will try to look at it soon 🤞🏼

@jamietanna jamietanna modified the milestones: v2.5.0, v2.6.0 May 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working server:strict
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants