Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3: revert ":sparkles: v3 (feature): use any as default Message type of Error struct (#1925)" #2000

Merged
merged 2 commits into from Aug 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
91 changes: 46 additions & 45 deletions app.go
Expand Up @@ -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.
Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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...)
Expand Down Expand Up @@ -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.
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
21 changes: 11 additions & 10 deletions app_test.go
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion ctx.go
Expand Up @@ -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
}
Expand Down
80 changes: 40 additions & 40 deletions helpers.go
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion router.go
Expand Up @@ -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 {
Expand Down