feat: add warning for multiple response body writes

Add a debug warning when attempting to write to the response body
multiple times. This helps developers identify subtle bugs where
middleware or handlers inadvertently write responses multiple times,
resulting in invalid output (e.g., concatenated JSON objects).

This change:
- Adds a warning in Context.Render() when Writer.Written() is true
- Follows the existing pattern used for header write warnings
- Only shows in debug mode via debugPrint()
- Is non-breaking and backward compatible

Fixes #4477

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
İsmail Daşcı 2026-01-17 20:41:36 +03:00
parent 3ab698dc51
commit fc23a46a1e
2 changed files with 21 additions and 0 deletions

View File

@ -1133,6 +1133,10 @@ func (c *Context) Render(code int, r render.Render) {
return
}
if c.Writer.Written() {
debugPrint("[WARNING] Response body already written. Attempting to write again with status code %d", code)
}
if err := r.Render(c.Writer); err != nil {
// Pushing error to c.Errors
_ = c.Error(err)

View File

@ -11,6 +11,7 @@ import (
"io"
"log"
"net/http"
"net/http/httptest"
"os"
"strings"
"sync"
@ -178,3 +179,19 @@ func TestGetMinVer(t *testing.T) {
_, e = getMinVer("go1.1.1.1")
require.Error(t, e)
}
func TestRenderWarnsOnMultipleWrites(t *testing.T) {
re := captureOutput(t, func() {
SetMode(DebugMode)
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
// First write
c.JSON(http.StatusOK, H{"first": "response"})
// Second write should trigger warning
c.JSON(http.StatusOK, H{"second": "response"})
SetMode(TestMode)
})
assert.Contains(t, re, "[WARNING] Response body already written")
}