diff --git a/middleware/recover.go b/middleware/recover.go index 7b6128533..36d41aa64 100644 --- a/middleware/recover.go +++ b/middleware/recover.go @@ -38,6 +38,11 @@ type ( // LogErrorFunc defines a function for custom logging in the middleware. // If it's set you don't need to provide LogLevel for config. LogErrorFunc LogErrorFunc + + // DisableErrorHandler disables the call to centralized HTTPErrorHandler. + // The recovered error is then passed back to upstream middleware, instead of swallowing the error. + // Optional. Default value false. + DisableErrorHandler bool `yaml:"disable_error_handler"` } ) @@ -50,6 +55,7 @@ var ( DisablePrintStack: false, LogLevel: 0, LogErrorFunc: nil, + DisableErrorHandler: false, } ) @@ -71,7 +77,7 @@ func RecoverWithConfig(config RecoverConfig) echo.MiddlewareFunc { } return func(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { + return func(c echo.Context) (returnErr error) { if config.Skipper(c) { return next(c) } @@ -113,7 +119,12 @@ func RecoverWithConfig(config RecoverConfig) echo.MiddlewareFunc { c.Logger().Print(msg) } } - c.Error(err) + + if(!config.DisableErrorHandler) { + c.Error(err) + } else { + returnErr = err + } } }() return next(c) diff --git a/middleware/recover_test.go b/middleware/recover_test.go index b27f3b41c..3e0d35d79 100644 --- a/middleware/recover_test.go +++ b/middleware/recover_test.go @@ -23,7 +23,8 @@ func TestRecover(t *testing.T) { h := Recover()(echo.HandlerFunc(func(c echo.Context) error { panic("test") })) - h(c) + err := h(c) + assert.NoError(t, err) assert.Equal(t, http.StatusInternalServerError, rec.Code) assert.Contains(t, buf.String(), "PANIC RECOVER") } @@ -163,3 +164,23 @@ func TestRecoverWithConfig_LogErrorFunc(t *testing.T) { assert.Contains(t, output, `"level":"ERROR"`) }) } + +func TestRecoverWithDisabled_ErrorHandler(t *testing.T) { + e := echo.New() + buf := new(bytes.Buffer) + e.Logger.SetOutput(buf) + req := httptest.NewRequest(http.MethodGet, "/", nil) + rec := httptest.NewRecorder() + c := e.NewContext(req, rec) + + config := DefaultRecoverConfig + config.DisableErrorHandler = true + h := RecoverWithConfig(config)(echo.HandlerFunc(func(c echo.Context) error { + panic("test") + })) + err := h(c) + + assert.Equal(t, http.StatusOK, rec.Code) + assert.Contains(t, buf.String(), "PANIC RECOVER") + assert.EqualError(t, err, "test") +}