Skip to content

Commit

Permalink
v3: revert ":sparkles: v3 (feature): use any as default Message type …
Browse files Browse the repository at this point in the history
…of Error struct (#1925)" (#2000)

Revert ":sparkles: v3 (feature): use any as default Message type of Error struct (#1925)"
  • Loading branch information
efectn committed Aug 8, 2022
1 parent 738e710 commit 4115929
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 97 deletions.
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

1 comment on commit 4115929

@ReneWerner87
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: 4115929 Previous: e5eb8d3 Ratio
Benchmark_Router_Handler 311.1 ns/op 0 B/op 0 allocs/op 153.9 ns/op 0 B/op 0 allocs/op 2.02
Benchmark_Router_Next 193.1 ns/op 0 B/op 0 allocs/op 93.51 ns/op 0 B/op 0 allocs/op 2.07
Benchmark_Router_Handler_StrictRouting 364.4 ns/op 0 B/op 0 allocs/op 144.1 ns/op 0 B/op 0 allocs/op 2.53
Benchmark_Cache 16173 ns/op 49367 B/op 6 allocs/op 316.2 ns/op 16 B/op 2 allocs/op 51.15
Benchmark_Cache_AdditionalHeaders 1426 ns/op 592 B/op 9 allocs/op 412.3 ns/op 16 B/op 2 allocs/op 3.46
Benchmark_Etag 251.5 ns/op 0 B/op 0 allocs/op 120.3 ns/op 0 B/op 0 allocs/op 2.09
Benchmark_Middleware_Favicon 231 ns/op 3 B/op 1 allocs/op 97.43 ns/op 3 B/op 1 allocs/op 2.37
Benchmark_Limiter 846.4 ns/op 72 B/op 2 allocs/op 317.7 ns/op 8 B/op 1 allocs/op 2.66

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.