diff --git a/HISTORY.md b/HISTORY.md index 118c344e..95b1836e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -31,11 +31,15 @@ The codebase for Dependency Injection, Internationalization and localization and - **New feature:** add the ability to set custom error handlers on path type parameters errors (existing or custom ones). Example Code: ```go -app.Macros().Get("uuid").HandleError(func(ctx iris.Context, err error) { +app.Macros().Get("uuid").HandleError(func(ctx iris.Context, paramIndex int, err error) { ctx.StatusCode(iris.StatusBadRequest) + + param := ctx.Params().GetEntryAt(paramIndex) ctx.JSON(iris.Map{ - "error": err.Error(), - "message": "invalid path parameter", + "error": err.Error(), + "message": "invalid path parameter", + "parameter": param.Key, + "value": param.ValueRaw, }) }) diff --git a/_examples/routing/dynamic-path/main.go b/_examples/routing/dynamic-path/main.go index 16146693..92a65539 100644 --- a/_examples/routing/dynamic-path/main.go +++ b/_examples/routing/dynamic-path/main.go @@ -153,11 +153,15 @@ func main() { // UUIDv4 (and v1) path parameter validation. // Optionally, set custom handler on path parameter type error: - app.Macros().Get("uuid").HandleError(func(ctx iris.Context, err error) { + app.Macros().Get("uuid").HandleError(func(ctx iris.Context, paramIndex int, err error) { ctx.StatusCode(iris.StatusBadRequest) + + param := ctx.Params().GetEntryAt(paramIndex) ctx.JSON(iris.Map{ - "error": err.Error(), - "message": "invalid path parameter", + "error": err.Error(), + "message": "invalid path parameter", + "parameter": param.Key, + "value": param.ValueRaw, }) }) diff --git a/macro/handler/handler.go b/macro/handler/handler.go index ce7a36e9..2cee25db 100644 --- a/macro/handler/handler.go +++ b/macro/handler/handler.go @@ -18,11 +18,11 @@ import ( // 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)). +// app.Macros().Get("uuid").HandleError(func(ctx iris.Context, paramIndex int, 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. +type ParamErrorHandler = func(*context.Context, int, 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). @@ -112,9 +112,8 @@ func MakeFilter(tmpl macro.Template) context.Filter { 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)) + p.HandleError.(ParamErrorHandler)(ctx, p.Index, value.(error)) } - return false } diff --git a/macro/macro.go b/macro/macro.go index 54e04260..14584037 100644 --- a/macro/macro.go +++ b/macro/macro.go @@ -315,7 +315,7 @@ func (m *Macro) Trailing() bool { // HandleError registers a handler which will be executed // when a parameter evaluator returns false and a non nil value which is a type of `error`. -// The "fnHandler" value MUST BE a type of `func(iris.Context, err error)`, +// The "fnHandler" value MUST BE a type of `func(iris.Context, paramIndex int, err error)`, // otherwise the program will receive a panic before server startup. // The status code of the ErrCode (`else` literal) is set // before the error handler but it can be modified inside the handler itself. diff --git a/macro/template.go b/macro/template.go index 33597ded..066af2ac 100644 --- a/macro/template.go +++ b/macro/template.go @@ -34,7 +34,7 @@ type TemplateParam struct { Name string `json:"name"` Index int `json:"index"` ErrCode int `json:"errCode"` - // Note that, the value MUST BE a type of `func(iris.Context, err error)`. + // Note that, the value MUST BE a type of `handler.ParamErrorHandler`. HandleError interface{} `json:"-"` /* It's not an typed value because of import-cycle, // neither a special struct required, see `handler.MakeFilter`. */ TypeEvaluator ParamEvaluator `json:"-"`