1
0
mirror of https://github.com/kataras/iris.git synced 2025-12-18 02:17:05 +00:00

NEW (HOT) FEATURE: Add custom error handlers on path type parameters error

This commit is contained in:
Gerasimos (Makis) Maropoulos
2021-02-14 15:31:27 +02:00
parent 567c06702f
commit 5990e7f432
7 changed files with 140 additions and 69 deletions

View File

@@ -3,11 +3,27 @@
package handler
import (
"fmt"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/core/memstore"
"github.com/kataras/iris/v12/macro"
)
// ParamErrorHandler is a special type of Iris handler which receives
// any error produced by a path type parameter evaluator and let developers
// customize the output instead of the
// provided error code 404 or anyother status code given on the `else` literal.
//
// Note that the builtin macros return error too, but they're handled
// by the `else` literal (error code). To change this behavior
// and send a custom error response you have to register it:
// app.Macros().Get("uuid").HandleError(func(iris.Context, err error)).
// You can also set custom macros by `app.Macros().Register`.
//
// See macro.HandleError to set it.
type ParamErrorHandler = func(*context.Context, error) // alias.
// CanMakeHandler reports whether a macro template needs a special macro's evaluator handler to be validated
// before procceed to the next handler(s).
// If the template does not contain any dynamic attributes and a special handler is NOT required
@@ -24,6 +40,13 @@ func CanMakeHandler(tmpl macro.Template) (needsMacroHandler bool) {
if p.CanEval() {
// if at least one needs it, then create the handler.
needsMacroHandler = true
if p.HandleError != nil {
// Check for its type.
if _, ok := p.HandleError.(ParamErrorHandler); !ok {
panic(fmt.Sprintf("HandleError must be a type of func(iris.Context, error) but got: %T", p.HandleError))
}
}
break
}
}
@@ -83,9 +106,15 @@ func MakeFilter(tmpl macro.Template) context.Filter {
return false
}
value := p.Eval(entry.String())
if value == nil {
ctx.StatusCode(p.ErrCode)
value, passed := p.Eval(entry.String())
if !passed {
ctx.StatusCode(p.ErrCode) // status code can change from an error handler, set it here.
if value != nil && p.HandleError != nil {
// The "value" is an error here, always (see template.Eval).
// This is always a type of ParamErrorHandler at this state (see CanMakeHandler).
p.HandleError.(ParamErrorHandler)(ctx, value.(error))
}
return false
}