From 9a4a4ea66a13546ec8bcd220fd063b25f4c3ef24 Mon Sep 17 00:00:00 2001 From: dylanhitt Date: Fri, 14 Feb 2025 12:44:34 -0500 Subject: [PATCH] feat: expose HandleHTTPError for use WithErrorHandler option --- engine_test.go | 9 +++++++++ errors.go | 14 +++++++++++--- errors_test.go | 22 ++++++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/engine_test.go b/engine_test.go index 6fc62572..19042085 100644 --- a/engine_test.go +++ b/engine_test.go @@ -18,6 +18,15 @@ func TestWithErrorHandler(t *testing.T) { errResponse := e.ErrorHandler(err) require.ErrorAs(t, errResponse, &HTTPError{}) }) + t.Run("with HandleHTTPError", func(t *testing.T) { + e := NewEngine( + WithErrorHandler(HandleHTTPError), + ) + err := errors.New("Not Found :c") + errResponse := e.ErrorHandler(err) + require.ErrorAs(t, errResponse, &HTTPError{}) + require.ErrorContains(t, errResponse, "500 Internal Server Error") + }) t.Run("custom handler", func(t *testing.T) { e := NewEngine( WithErrorHandler(func(err error) error { diff --git a/errors.go b/errors.go index fd37a0ce..33d68364 100644 --- a/errors.go +++ b/errors.go @@ -147,7 +147,7 @@ func (e NotAcceptableError) Unwrap() error { return HTTPError(e) } // ErrorHandler is the default error handler used by the framework. // If the error is an [HTTPError] that error is returned. // If the error adheres to the [ErrorWithStatus] and/or [ErrorWithDetail] interface -// the error is transformed to a [HTTPError]. +// the error is transformed to a [HTTPError] using [HandleHTTPError]. // If the error is not an [HTTPError] nor does it adhere to an // interface the error is returned as is. func ErrorHandler(err error) error { @@ -155,13 +155,21 @@ func ErrorHandler(err error) error { switch { case errors.As(err, &HTTPError{}), errors.As(err, &errorStatus): - return handleHTTPError(err) + return HandleHTTPError(err) } return err } -func handleHTTPError(err error) HTTPError { +// HandleHTTPError is the core logic +// of handling fuego [HTTPError]'s. This +// function takes any error and coerces it into a fuego HTTPError. +// This can be used override the default handler: +// +// engine := fuego.NewEngine( +// WithErrorHandler(HandleHTTPError), +// ) +func HandleHTTPError(err error) error { errResponse := HTTPError{ Err: err, } diff --git a/errors_test.go b/errors_test.go index 0fea5b14..8a7dfa68 100644 --- a/errors_test.go +++ b/errors_test.go @@ -116,6 +116,28 @@ func TestErrorHandler(t *testing.T) { }) } +func TestHandleHTTPError(t *testing.T) { + t.Run("should always be HTTPError", func(t *testing.T) { + err := errors.New("test error") + + errResponse := HandleHTTPError(err) + require.ErrorAs(t, errResponse, &HTTPError{}) + require.ErrorContains(t, errResponse, "500 Internal Server Error") + }) + + t.Run("not found error", func(t *testing.T) { + err := NotFoundError{ + Err: errors.New("Not Found :c"), + } + errResponse := HandleHTTPError(err) + require.ErrorAs(t, errResponse, &HTTPError{}) + require.ErrorContains(t, err, "Not Found :c") + require.ErrorContains(t, errResponse, "Not Found") + require.ErrorContains(t, errResponse, "404") + require.Equal(t, http.StatusNotFound, errResponse.(HTTPError).StatusCode()) + }) +} + func TestHTTPError_Error(t *testing.T) { t.Run("title", func(t *testing.T) { t.Run("custom title", func(t *testing.T) {