mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-01-08 09:14:37 +02:00
[#2957] added support for wrapped api errors
This commit is contained in:
parent
ac52befb5b
commit
1e4c665b53
@ -91,6 +91,8 @@
|
|||||||
|
|
||||||
- Added `?download` file query parameter option to instruct the browser to always download a file and not show a preview.
|
- Added `?download` file query parameter option to instruct the browser to always download a file and not show a preview.
|
||||||
|
|
||||||
|
- Added support for wrapped API errors (_in case Go 1.20+ is used with multiple wrapped errors, `apis.ApiError` takes precedence_).
|
||||||
|
|
||||||
|
|
||||||
## v0.16.10
|
## v0.16.10
|
||||||
|
|
||||||
|
22
apis/base.go
22
apis/base.go
@ -52,6 +52,10 @@ func InitApi(app core.App) (*echo.Echo, error) {
|
|||||||
|
|
||||||
// custom error handler
|
// custom error handler
|
||||||
e.HTTPErrorHandler = func(c echo.Context, err error) {
|
e.HTTPErrorHandler = func(c echo.Context, err error) {
|
||||||
|
if err == nil {
|
||||||
|
return // no error
|
||||||
|
}
|
||||||
|
|
||||||
if c.Response().Committed {
|
if c.Response().Committed {
|
||||||
if app.IsDebug() {
|
if app.IsDebug() {
|
||||||
log.Println("HTTPErrorHandler response was already committed:", err)
|
log.Println("HTTPErrorHandler response was already committed:", err)
|
||||||
@ -61,24 +65,22 @@ func InitApi(app core.App) (*echo.Echo, error) {
|
|||||||
|
|
||||||
var apiErr *ApiError
|
var apiErr *ApiError
|
||||||
|
|
||||||
switch v := err.(type) {
|
if errors.As(err, &apiErr) {
|
||||||
case *echo.HTTPError:
|
if app.IsDebug() && apiErr.RawData() != nil {
|
||||||
|
log.Println(apiErr.RawData())
|
||||||
|
}
|
||||||
|
} else if v := new(echo.HTTPError); errors.As(err, &v) {
|
||||||
if v.Internal != nil && app.IsDebug() {
|
if v.Internal != nil && app.IsDebug() {
|
||||||
log.Println(v.Internal)
|
log.Println(v.Internal)
|
||||||
}
|
}
|
||||||
msg := fmt.Sprintf("%v", v.Message)
|
msg := fmt.Sprintf("%v", v.Message)
|
||||||
apiErr = NewApiError(v.Code, msg, v)
|
apiErr = NewApiError(v.Code, msg, v)
|
||||||
case *ApiError:
|
} else {
|
||||||
if app.IsDebug() && v.RawData() != nil {
|
if app.IsDebug() {
|
||||||
log.Println(v.RawData())
|
|
||||||
}
|
|
||||||
apiErr = v
|
|
||||||
default:
|
|
||||||
if err != nil && app.IsDebug() {
|
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil && errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
apiErr = NewNotFoundError("", err)
|
apiErr = NewNotFoundError("", err)
|
||||||
} else {
|
} else {
|
||||||
apiErr = NewBadRequestError("", err)
|
apiErr = NewBadRequestError("", err)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package apis_test
|
package apis_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -314,3 +315,88 @@ func TestEagerRequestInfoCache(t *testing.T) {
|
|||||||
scenario.Test(t)
|
scenario.Test(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestErrorHandler(t *testing.T) {
|
||||||
|
scenarios := []tests.ApiScenario{
|
||||||
|
{
|
||||||
|
Name: "apis.ApiError",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Url: "/test",
|
||||||
|
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
|
||||||
|
e.GET("/test", func(c echo.Context) error {
|
||||||
|
return apis.NewApiError(418, "test", nil)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ExpectedStatus: 418,
|
||||||
|
ExpectedContent: []string{`"message":"Test."`},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "wrapped apis.ApiError",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Url: "/test",
|
||||||
|
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
|
||||||
|
e.GET("/test", func(c echo.Context) error {
|
||||||
|
return fmt.Errorf("example 123: %w", apis.NewApiError(418, "test", nil))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ExpectedStatus: 418,
|
||||||
|
ExpectedContent: []string{`"message":"Test."`},
|
||||||
|
NotExpectedContent: []string{"example", "123"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "echo.HTTPError",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Url: "/test",
|
||||||
|
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
|
||||||
|
e.GET("/test", func(c echo.Context) error {
|
||||||
|
return echo.NewHTTPError(418, "test")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ExpectedStatus: 418,
|
||||||
|
ExpectedContent: []string{`"message":"Test."`},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "wrapped echo.HTTPError",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Url: "/test",
|
||||||
|
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
|
||||||
|
e.GET("/test", func(c echo.Context) error {
|
||||||
|
return fmt.Errorf("example 123: %w", echo.NewHTTPError(418, "test"))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ExpectedStatus: 418,
|
||||||
|
ExpectedContent: []string{`"message":"Test."`},
|
||||||
|
NotExpectedContent: []string{"example", "123"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "wrapped sql.ErrNoRows",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Url: "/test",
|
||||||
|
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
|
||||||
|
e.GET("/test", func(c echo.Context) error {
|
||||||
|
return fmt.Errorf("example 123: %w", sql.ErrNoRows)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ExpectedStatus: 404,
|
||||||
|
ExpectedContent: []string{`"data":{}`},
|
||||||
|
NotExpectedContent: []string{"example", "123"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "custom error",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Url: "/test",
|
||||||
|
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
|
||||||
|
e.GET("/test", func(c echo.Context) error {
|
||||||
|
return fmt.Errorf("example 123")
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ExpectedStatus: 400,
|
||||||
|
ExpectedContent: []string{`"data":{}`},
|
||||||
|
NotExpectedContent: []string{"example", "123"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, scenario := range scenarios {
|
||||||
|
scenario.Test(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user