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.
This commit is contained in:
git-hulk 2022-11-07 16:30:37 +08:00
parent aefae309a4
commit b7682616db
2 changed files with 21 additions and 6 deletions

View File

@ -54,10 +54,7 @@ var (
// Render (JSON) writes data with custom ContentType. // Render (JSON) writes data with custom ContentType.
func (r JSON) Render(w http.ResponseWriter) (err error) { func (r JSON) Render(w http.ResponseWriter) (err error) {
if err = WriteJSON(w, r.Data); err != nil { return WriteJSON(w, r.Data)
panic(err)
}
return
} }
// WriteContentType (JSON) writes JSON ContentType. // WriteContentType (JSON) writes JSON ContentType.

View File

@ -39,12 +39,30 @@ func TestRenderJSON(t *testing.T) {
assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type")) 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() w := httptest.NewRecorder()
data := make(chan int) data := make(chan int)
// json: unsupported type: 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) { func TestRenderIndentedJSON(t *testing.T) {