From b7682616dbed0c9e930239cdae4759326499b462 Mon Sep 17 00:00:00 2001 From: git-hulk Date: Mon, 7 Nov 2022 16:30:37 +0800 Subject: [PATCH] Don't panic when failed to render or write JSON Currently, gin will panic if failed to write JSON to client and it's unnecessary for most scenarios. Because most of them are caused by network error like connection reset or timeout, it'd be better to retrieve an error instead of panic. --- render/json.go | 5 +---- render/render_test.go | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/render/json.go b/render/json.go index af678e80d1..55c441fab9 100644 --- a/render/json.go +++ b/render/json.go @@ -54,10 +54,7 @@ var ( // Render (JSON) writes data with custom ContentType. func (r JSON) Render(w http.ResponseWriter) (err error) { - if err = WriteJSON(w, r.Data); err != nil { - panic(err) - } - return + return WriteJSON(w, r.Data) } // WriteContentType (JSON) writes JSON ContentType. diff --git a/render/render_test.go b/render/render_test.go index 3509db3cec..f49294127c 100644 --- a/render/render_test.go +++ b/render/render_test.go @@ -39,12 +39,30 @@ func TestRenderJSON(t *testing.T) { assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type")) } -func TestRenderJSONPanics(t *testing.T) { +func TestRenderJSONFail(t *testing.T) { w := httptest.NewRecorder() data := make(chan int) // json: unsupported type: chan int - assert.Panics(t, func() { assert.NoError(t, (JSON{data}).Render(w)) }) + assert.Error(t, (JSON{data}).Render(w)) +} + +type mockWriter struct { + *httptest.ResponseRecorder +} + +func (mock *mockWriter) Write(buf []byte) (int, error) { + return 0, errors.New("mock write error") +} + +func TestRenderJSONWriteFail(t *testing.T) { + w := &mockWriter{ + ResponseRecorder: httptest.NewRecorder(), + } + err := (JSON{map[string]any{ + "foo": "bar", + }}).Render(w) + assert.Equal(t, errors.New("mock write error"), err) } func TestRenderIndentedJSON(t *testing.T) {