Skip to content
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

response.WriteHeader method has been called more than once while handling an HTTP request #3491

Open
Xib1uvXi opened this issue Dec 17, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@Xib1uvXi
Copy link

What happened:

image

Environment:

  • Kratos version (use kratos -v):
  • Go version (use go version): go version go1.23.2
  • OS (e.g: cat /etc/os-release): linux / arm64
@Xib1uvXi Xib1uvXi added the bug Something isn't working label Dec 17, 2024
@Xib1uvXi
Copy link
Author

Kratos version: v2.8.2

Copy link

dosubot bot commented Dec 17, 2024

Hey @Xib1uvXi! I'm here to assist you with any Kratos issues you're facing. I can help you with bug fixes, answer questions, and guide you on becoming a contributor. Let's tackle this together!

The issue with response.WriteHeader being called more than once in the Go-Kratos framework, specifically from the http.DefaultErrorEncoder in codec.go at line 116, occurs because WriteHeader is called both when an error occurs during marshaling and again after setting the content type and before writing the response body.

To resolve this issue, ensure that WriteHeader is only called once. You can modify the DefaultErrorEncoder function to set a flag or return early if WriteHeader has already been called due to an error. Here's a possible solution:

func DefaultErrorEncoder(w http.ResponseWriter, r *http.Request, err error) {
    se := errors.FromError(err)
    codec, _ := CodecForRequest(r, "Accept")
    body, marshalErr := codec.Marshal(se)
    if marshalErr != nil {
        w.WriteHeader(http.StatusInternalServerError)
        return
    }
    w.Header().Set("Content-Type", httputil.ContentType(codec.Name()))
    if !w.Header().Written() { // Check if WriteHeader has already been called
        w.WriteHeader(int(se.Code))
    }
    _, _ = w.Write(body)
}

This solution assumes that w.Header().Written() is a method that checks if WriteHeader has already been called. If such a method does not exist, you may need to implement a custom mechanism to track whether WriteHeader has been called [1].

To continue talking to Dosu, mention @dosu.


Help Dosu learn! Give it feedback: Great Response | Irrelevant Answer | Incorrect Sources | Too Verbose | Hallucination | Other

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant