diff --git a/app.go b/app.go index 91dcea2d07..3ccda5243c 100644 --- a/app.go +++ b/app.go @@ -72,22 +72,23 @@ type Storage interface { // ErrorHandler defines a function that will process all errors // returned from any handlers in the stack -// cfg := fiber.Config{} -// cfg.ErrorHandler = func(c *DefaultCtx, err error) error { -// code := StatusInternalServerError -// if e, ok := err.(*Error); ok { -// code = e.Code -// } -// c.Set(HeaderContentType, MIMETextPlainCharsetUTF8) -// return c.Status(code).SendString(err.Error()) -// } -// app := fiber.New(cfg) +// +// cfg := fiber.Config{} +// cfg.ErrorHandler = func(c *DefaultCtx, err error) error { +// code := StatusInternalServerError +// if e, ok := err.(*Error); ok { +// code = e.Code +// } +// c.Set(HeaderContentType, MIMETextPlainCharsetUTF8) +// return c.Status(code).SendString(err.Error()) +// } +// app := fiber.New(cfg) type ErrorHandler = func(Ctx, error) error // Error represents an error that occurred while handling a request. type Error struct { - Code int `json:"code"` - Message any `json:"message"` + Code int `json:"code"` + Message string `json:"message"` } // App denotes the Fiber application. @@ -436,12 +437,15 @@ var DefaultErrorHandler = func(c Ctx, err error) error { } // New creates a new Fiber named instance. -// app := fiber.New() +// +// app := fiber.New() +// // You can pass optional configuration options by passing a Config struct: -// app := fiber.New(fiber.Config{ -// Prefork: true, -// ServerHeader: "Fiber", -// }) +// +// app := fiber.New(fiber.Config{ +// Prefork: true, +// ServerHeader: "Fiber", +// }) func New(config ...Config) *App { // Create a new app app := &App{ @@ -605,15 +609,15 @@ func (app *App) GetRoute(name string) Route { // Use registers a middleware route that will match requests // with the provided prefix (which is optional and defaults to "/"). // -// app.Use(func(c fiber.Ctx) error { -// return c.Next() -// }) -// app.Use("/api", func(c fiber.Ctx) error { -// return c.Next() -// }) -// app.Use("/api", handler, func(c fiber.Ctx) error { -// return c.Next() -// }) +// app.Use(func(c fiber.Ctx) error { +// return c.Next() +// }) +// app.Use("/api", func(c fiber.Ctx) error { +// return c.Next() +// }) +// app.Use("/api", handler, func(c fiber.Ctx) error { +// return c.Next() +// }) // // This method will match all HTTP verbs: GET, POST, PUT, HEAD etc... func (app *App) Use(args ...any) Router { @@ -706,8 +710,9 @@ func (app *App) All(path string, handlers ...Handler) Router { } // Group is used for Routes with common prefix to define a new sub-router with optional middleware. -// api := app.Group("/api") -// api.Get("/users", handler) +// +// api := app.Group("/api") +// api.Get("/users", handler) func (app *App) Group(prefix string, handlers ...Handler) Router { if len(handlers) > 0 { app.register(methodUse, prefix, handlers...) @@ -737,25 +742,19 @@ func (app *App) Route(prefix string, fn func(router Router), name ...string) Rou // Error makes it compatible with the `error` interface. func (e *Error) Error() string { - return fmt.Sprint(e.Message) + return e.Message } -// NewErrors creates multiple/single new Error instances. -// If you want to pass single message, you have to pass 1 message. -// To pass multiple error messages, you have to pass +2 messages. -func NewErrors(code int, messages ...any) *Error { - e := &Error{ +// NewError creates a new Error instance with an optional message +func NewError(code int, message ...string) *Error { + err := &Error{ Code: code, Message: utils.StatusMessage(code), } - - if len(messages) == 1 { - e.Message = messages[0] - } else if len(messages) > 1 { - e.Message = messages + if len(message) > 0 { + err.Message = message[0] } - - return e + return err } // Listener can be used to pass a custom listener. @@ -781,8 +780,8 @@ func (app *App) Listener(ln net.Listener) error { // Listen serves HTTP requests from the given addr. // -// app.Listen(":8080") -// app.Listen("127.0.0.1:8080") +// app.Listen(":8080") +// app.Listen("127.0.0.1:8080") func (app *App) Listen(addr string) error { // Start prefork if app.config.Prefork { @@ -809,7 +808,8 @@ func (app *App) Listen(addr string) error { // ListenTLS serves HTTPS requests from the given addr. // certFile and keyFile are the paths to TLS certificate and key file: -// app.ListenTLS(":8080", "./cert.pem", "./cert.key") +// +// app.ListenTLS(":8080", "./cert.pem", "./cert.key") func (app *App) ListenTLS(addr, certFile, keyFile string) error { // Check for valid cert/key path if len(certFile) == 0 || len(keyFile) == 0 { @@ -850,7 +850,8 @@ func (app *App) ListenTLS(addr, certFile, keyFile string) error { // ListenMutualTLS serves HTTPS requests from the given addr. // certFile, keyFile and clientCertFile are the paths to TLS certificate and key file: -// app.ListenMutualTLS(":8080", "./cert.pem", "./cert.key", "./client.pem") +// +// app.ListenMutualTLS(":8080", "./cert.pem", "./cert.key", "./client.pem") func (app *App) ListenMutualTLS(addr, certFile, keyFile, clientCertFile string) error { // Check for valid cert/key path if len(certFile) == 0 || len(keyFile) == 0 { diff --git a/app_test.go b/app_test.go index 55250bdae1..99b3167e01 100644 --- a/app_test.go +++ b/app_test.go @@ -1252,17 +1252,18 @@ func Benchmark_AcquireCtx(b *testing.B) { } } -// go test -run Test_NewErrors -func Test_NewErrors(t *testing.T) { - e := NewErrors(StatusForbidden, "permission denied") - utils.AssertEqual(t, StatusForbidden, e.Code) - utils.AssertEqual(t, "permission denied", fmt.Sprint(e.Message)) +// go test -v -run=^$ -bench=Benchmark_NewError -benchmem -count=4 +func Benchmark_NewError(b *testing.B) { + for n := 0; n < b.N; n++ { + NewError(200, "test") + } +} - e = NewErrors(StatusBadRequest, "error 1", "error 2") - messages := e.Message.([]interface{}) - utils.AssertEqual(t, StatusBadRequest, e.Code) - utils.AssertEqual(t, "error 1", fmt.Sprint(messages[0])) - utils.AssertEqual(t, "error 2", fmt.Sprint(messages[1])) +// go test -run Test_NewError +func Test_NewError(t *testing.T) { + e := NewError(StatusForbidden, "permission denied") + utils.AssertEqual(t, StatusForbidden, e.Code) + utils.AssertEqual(t, "permission denied", e.Message) } // go test -run Test_Test_Timeout diff --git a/ctx.go b/ctx.go index 3494623a8e..642cca3d61 100644 --- a/ctx.go +++ b/ctx.go @@ -1375,7 +1375,7 @@ func (c *DefaultCtx) SendFile(file string, compress ...bool) error { } // Check for error if status != StatusNotFound && fsStatus == StatusNotFound { - return NewErrors(StatusNotFound, fmt.Sprintf("sendfile: file %s not found", filename)) + return NewError(StatusNotFound, fmt.Sprintf("sendfile: file %s not found", filename)) } return nil } diff --git a/helpers.go b/helpers.go index b061c50998..bc478ad4bf 100644 --- a/helpers.go +++ b/helpers.go @@ -497,46 +497,46 @@ const ( // Errors var ( - ErrBadRequest = NewErrors(StatusBadRequest) // RFC 7231, 6.5.1 - ErrUnauthorized = NewErrors(StatusUnauthorized) // RFC 7235, 3.1 - ErrPaymentRequired = NewErrors(StatusPaymentRequired) // RFC 7231, 6.5.2 - ErrForbidden = NewErrors(StatusForbidden) // RFC 7231, 6.5.3 - ErrNotFound = NewErrors(StatusNotFound) // RFC 7231, 6.5.4 - ErrMethodNotAllowed = NewErrors(StatusMethodNotAllowed) // RFC 7231, 6.5.5 - ErrNotAcceptable = NewErrors(StatusNotAcceptable) // RFC 7231, 6.5.6 - ErrProxyAuthRequired = NewErrors(StatusProxyAuthRequired) // RFC 7235, 3.2 - ErrRequestTimeout = NewErrors(StatusRequestTimeout) // RFC 7231, 6.5.7 - ErrConflict = NewErrors(StatusConflict) // RFC 7231, 6.5.8 - ErrGone = NewErrors(StatusGone) // RFC 7231, 6.5.9 - ErrLengthRequired = NewErrors(StatusLengthRequired) // RFC 7231, 6.5.10 - ErrPreconditionFailed = NewErrors(StatusPreconditionFailed) // RFC 7232, 4.2 - ErrRequestEntityTooLarge = NewErrors(StatusRequestEntityTooLarge) // RFC 7231, 6.5.11 - ErrRequestURITooLong = NewErrors(StatusRequestURITooLong) // RFC 7231, 6.5.12 - ErrUnsupportedMediaType = NewErrors(StatusUnsupportedMediaType) // RFC 7231, 6.5.13 - ErrRequestedRangeNotSatisfiable = NewErrors(StatusRequestedRangeNotSatisfiable) // RFC 7233, 4.4 - ErrExpectationFailed = NewErrors(StatusExpectationFailed) // RFC 7231, 6.5.14 - ErrTeapot = NewErrors(StatusTeapot) // RFC 7168, 2.3.3 - ErrMisdirectedRequest = NewErrors(StatusMisdirectedRequest) // RFC 7540, 9.1.2 - ErrUnprocessableEntity = NewErrors(StatusUnprocessableEntity) // RFC 4918, 11.2 - ErrLocked = NewErrors(StatusLocked) // RFC 4918, 11.3 - ErrFailedDependency = NewErrors(StatusFailedDependency) // RFC 4918, 11.4 - ErrTooEarly = NewErrors(StatusTooEarly) // RFC 8470, 5.2. - ErrUpgradeRequired = NewErrors(StatusUpgradeRequired) // RFC 7231, 6.5.15 - ErrPreconditionRequired = NewErrors(StatusPreconditionRequired) // RFC 6585, 3 - ErrTooManyRequests = NewErrors(StatusTooManyRequests) // RFC 6585, 4 - ErrRequestHeaderFieldsTooLarge = NewErrors(StatusRequestHeaderFieldsTooLarge) // RFC 6585, 5 - ErrUnavailableForLegalReasons = NewErrors(StatusUnavailableForLegalReasons) // RFC 7725, 3 - ErrInternalServerError = NewErrors(StatusInternalServerError) // RFC 7231, 6.6.1 - ErrNotImplemented = NewErrors(StatusNotImplemented) // RFC 7231, 6.6.2 - ErrBadGateway = NewErrors(StatusBadGateway) // RFC 7231, 6.6.3 - ErrServiceUnavailable = NewErrors(StatusServiceUnavailable) // RFC 7231, 6.6.4 - ErrGatewayTimeout = NewErrors(StatusGatewayTimeout) // RFC 7231, 6.6.5 - ErrHTTPVersionNotSupported = NewErrors(StatusHTTPVersionNotSupported) // RFC 7231, 6.6.6 - ErrVariantAlsoNegotiates = NewErrors(StatusVariantAlsoNegotiates) // RFC 2295, 8.1 - ErrInsufficientStorage = NewErrors(StatusInsufficientStorage) // RFC 4918, 11.5 - ErrLoopDetected = NewErrors(StatusLoopDetected) // RFC 5842, 7.2 - ErrNotExtended = NewErrors(StatusNotExtended) // RFC 2774, 7 - ErrNetworkAuthenticationRequired = NewErrors(StatusNetworkAuthenticationRequired) // RFC 6585, 6 + ErrBadRequest = NewError(StatusBadRequest) // RFC 7231, 6.5.1 + ErrUnauthorized = NewError(StatusUnauthorized) // RFC 7235, 3.1 + ErrPaymentRequired = NewError(StatusPaymentRequired) // RFC 7231, 6.5.2 + ErrForbidden = NewError(StatusForbidden) // RFC 7231, 6.5.3 + ErrNotFound = NewError(StatusNotFound) // RFC 7231, 6.5.4 + ErrMethodNotAllowed = NewError(StatusMethodNotAllowed) // RFC 7231, 6.5.5 + ErrNotAcceptable = NewError(StatusNotAcceptable) // RFC 7231, 6.5.6 + ErrProxyAuthRequired = NewError(StatusProxyAuthRequired) // RFC 7235, 3.2 + ErrRequestTimeout = NewError(StatusRequestTimeout) // RFC 7231, 6.5.7 + ErrConflict = NewError(StatusConflict) // RFC 7231, 6.5.8 + ErrGone = NewError(StatusGone) // RFC 7231, 6.5.9 + ErrLengthRequired = NewError(StatusLengthRequired) // RFC 7231, 6.5.10 + ErrPreconditionFailed = NewError(StatusPreconditionFailed) // RFC 7232, 4.2 + ErrRequestEntityTooLarge = NewError(StatusRequestEntityTooLarge) // RFC 7231, 6.5.11 + ErrRequestURITooLong = NewError(StatusRequestURITooLong) // RFC 7231, 6.5.12 + ErrUnsupportedMediaType = NewError(StatusUnsupportedMediaType) // RFC 7231, 6.5.13 + ErrRequestedRangeNotSatisfiable = NewError(StatusRequestedRangeNotSatisfiable) // RFC 7233, 4.4 + ErrExpectationFailed = NewError(StatusExpectationFailed) // RFC 7231, 6.5.14 + ErrTeapot = NewError(StatusTeapot) // RFC 7168, 2.3.3 + ErrMisdirectedRequest = NewError(StatusMisdirectedRequest) // RFC 7540, 9.1.2 + ErrUnprocessableEntity = NewError(StatusUnprocessableEntity) // RFC 4918, 11.2 + ErrLocked = NewError(StatusLocked) // RFC 4918, 11.3 + ErrFailedDependency = NewError(StatusFailedDependency) // RFC 4918, 11.4 + ErrTooEarly = NewError(StatusTooEarly) // RFC 8470, 5.2. + ErrUpgradeRequired = NewError(StatusUpgradeRequired) // RFC 7231, 6.5.15 + ErrPreconditionRequired = NewError(StatusPreconditionRequired) // RFC 6585, 3 + ErrTooManyRequests = NewError(StatusTooManyRequests) // RFC 6585, 4 + ErrRequestHeaderFieldsTooLarge = NewError(StatusRequestHeaderFieldsTooLarge) // RFC 6585, 5 + ErrUnavailableForLegalReasons = NewError(StatusUnavailableForLegalReasons) // RFC 7725, 3 + ErrInternalServerError = NewError(StatusInternalServerError) // RFC 7231, 6.6.1 + ErrNotImplemented = NewError(StatusNotImplemented) // RFC 7231, 6.6.2 + ErrBadGateway = NewError(StatusBadGateway) // RFC 7231, 6.6.3 + ErrServiceUnavailable = NewError(StatusServiceUnavailable) // RFC 7231, 6.6.4 + ErrGatewayTimeout = NewError(StatusGatewayTimeout) // RFC 7231, 6.6.5 + ErrHTTPVersionNotSupported = NewError(StatusHTTPVersionNotSupported) // RFC 7231, 6.6.6 + ErrVariantAlsoNegotiates = NewError(StatusVariantAlsoNegotiates) // RFC 2295, 8.1 + ErrInsufficientStorage = NewError(StatusInsufficientStorage) // RFC 4918, 11.5 + ErrLoopDetected = NewError(StatusLoopDetected) // RFC 5842, 7.2 + ErrNotExtended = NewError(StatusNotExtended) // RFC 2774, 7 + ErrNetworkAuthenticationRequired = NewError(StatusNetworkAuthenticationRequired) // RFC 6585, 6 ) // HTTP Headers were copied from net/http. diff --git a/router.go b/router.go index 4faa56ae92..cf048b35c2 100644 --- a/router.go +++ b/router.go @@ -134,7 +134,7 @@ func (app *App) next(c CustomCtx, customCtx bool) (match bool, err error) { } // If c.Next() does not match, return 404 - err = NewErrors(StatusNotFound, "Cannot "+c.Method()+" "+c.getPathOriginal()) + err = NewError(StatusNotFound, "Cannot "+c.Method()+" "+c.getPathOriginal()) var isMethodExist bool if customCtx {