Description

I use gin to launch a service that provides a download interface.
When the client downloads a 20MB file, if there is a problem with the server processing when downloading to 10MB, it should return an error message of 500 to the client, informing them of an internal server error.
The client received an httpcode of 200, but the server printed a warning log indicating that 500 cannot overwrite 200.

How to reproduce

The actual code is quite long, so I have extracted important parts

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    g := gin.Default()
    g.GET("/hello/:name", func(c *gin.Context) {
        c.String(200, "Hello %s", c.Param("name"))
    })
    g.Run(":9000")
}

func exampleDemo(g *gin.Context){
    // use this method write data
    g.Writer.Write(bs)

    // use xml to set error code and msg
    if err != nil {
        g.XML(500,errorxml)
    }
}

Expectations

server no warning info, server respose http code 500 to client

Actual result

[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 200 with 500

client can receive 10M data from response, http code is 200

Environment

  • go version: v1.20.10
  • gin version (or commit ref): v1.9.1
  • operating system: macOS 14.4

Comment From: JimChenWYU

Gin [GIN-debug] [WARNING] Headers were already written. Wanted to override status code 200 with 500

check your code, if response 200 before return 500 or not ?

Comment From: T-TRz879

use g.Writer.Write will default to returning 200,when returning the stream to the client, an exception may occur where the code and header have already reached the client Gin [GIN-debug] [WARNING] Headers were already written. Wanted to override status code 200 with 500

Comment From: JimChenWYU

If you just want to temporarily store data, you can

var tmp bytes.Buffer
tmp.Write(bs)

finally like:

func exampleDemo(g *gin.Context){
    // save data
    var tmp bytes.Buffer
        tmp.Write(bs)

    // use xml to set error code and msg
    if err != nil {
        g.XML(500,errorxml)
                return
    }

        // success
       g.Writer.Write(b.Bytes())
}

Comment From: T-TRz879

It's impossible,data bytes maybe 2G or bigger. I think it is not a bug, it's my problem

Comment From: jexlor

Have same problem.. any solution?

gin is trying to override status code 500 with 200 when i clearly say that in case of an error return status code 500.