From cc62cdfffc887b1abf3b36aca0a53a4b9e30abc6 Mon Sep 17 00:00:00 2001 From: chenyahui Date: Fri, 28 Apr 2023 16:09:50 +0800 Subject: [PATCH 1/2] Only push net error to c.Errors and panic others errors --- context.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/context.go b/context.go index 5716318e1f..ba2dfcbd55 100644 --- a/context.go +++ b/context.go @@ -924,9 +924,13 @@ func (c *Context) Render(code int, r render.Render) { } if err := r.Render(c.Writer); err != nil { - // Pushing error to c.Errors - _ = c.Error(err) - c.Abort() + // if err is net error, pushing error to c.Errors + if _, ok := err.(*net.OpError); ok { + _ = c.Error(err) + c.Abort() + } else { + panic(err) + } } } From ce03fdda7d9a13288eb16721619d4a97f7983a1b Mon Sep 17 00:00:00 2001 From: chenyahui Date: Sun, 30 Apr 2023 22:52:56 +0800 Subject: [PATCH 2/2] add unit tests for RenderPanic and RenderIfNetErr --- context.go | 3 ++- context_test.go | 42 +++++++++++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/context.go b/context.go index ba2dfcbd55..b711222098 100644 --- a/context.go +++ b/context.go @@ -925,7 +925,8 @@ func (c *Context) Render(code int, r render.Render) { if err := r.Render(c.Writer); err != nil { // if err is net error, pushing error to c.Errors - if _, ok := err.(*net.OpError); ok { + netOpErr := &net.OpError{} + if ok := errors.As(err, &netOpErr); ok { _ = c.Error(err) c.Abort() } else { diff --git a/context_test.go b/context_test.go index 1dec902c69..2f0bf34572 100644 --- a/context_test.go +++ b/context_test.go @@ -32,7 +32,15 @@ import ( var _ context.Context = (*Context)(nil) -var errTestRender = errors.New("TestRender") +var errTestRender = errors.New("TestPanicRender") + +var errNetOpErr = &net.OpError{ + Op: "testneterr", + Net: "", + Source: nil, + Addr: nil, + Err: nil, +} // Unit tests TODO // func (c *Context) File(filepath string) { @@ -645,21 +653,41 @@ func TestContextBodyAllowedForStatus(t *testing.T) { assert.True(t, true, bodyAllowedForStatus(http.StatusInternalServerError)) } -type TestRender struct{} +type TestPanicRender struct{} -func (*TestRender) Render(http.ResponseWriter) error { +func (*TestPanicRender) Render(http.ResponseWriter) error { return errTestRender } -func (*TestRender) WriteContentType(http.ResponseWriter) {} +func (*TestPanicRender) WriteContentType(http.ResponseWriter) {} + +func TestContextRenderPanicIfErr(t *testing.T) { + defer func() { + r := recover() + assert.Equal(t, fmt.Sprint(errTestRender), fmt.Sprint(r)) + }() + + w := httptest.NewRecorder() + c, _ := CreateTestContext(w) + + c.Render(http.StatusOK, &TestPanicRender{}) +} + +type TestNetErrorRender struct{} + +func (*TestNetErrorRender) Render(http.ResponseWriter) error { + return errNetOpErr +} + +func (*TestNetErrorRender) WriteContentType(http.ResponseWriter) {} -func TestContextRenderIfErr(t *testing.T) { +func TestContextRenderIfNetErr(t *testing.T) { w := httptest.NewRecorder() c, _ := CreateTestContext(w) - c.Render(http.StatusOK, &TestRender{}) + c.Render(http.StatusOK, &TestNetErrorRender{}) - assert.Equal(t, errorMsgs{&Error{Err: errTestRender, Type: 1}}, c.Errors) + assert.Equal(t, errorMsgs{&Error{Err: errNetOpErr, Type: 1}}, c.Errors) } // Tests that the response is serialized as JSON