From dee7a13cbafd6a1248233b75ad9b2f91d0745cc0 Mon Sep 17 00:00:00 2001 From: mikestefanello Date: Tue, 14 Dec 2021 20:54:47 -0500 Subject: [PATCH] Add support for better validation error messages. --- controller/controller.go | 30 ++++++++++++++++++++++++++++++ routes/login.go | 6 +++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index eaf41e2..3f5335e 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -7,6 +7,7 @@ import ( "net/http" "path" "path/filepath" + "reflect" "runtime" "sync" @@ -14,6 +15,9 @@ import ( "goweb/container" "goweb/funcmap" "goweb/middleware" + "goweb/msg" + + "github.com/go-playground/validator/v10" "github.com/eko/gocache/v2/marshaler" @@ -151,6 +155,32 @@ func (t *Controller) Redirect(c echo.Context, route string, routeParams ...inter return c.Redirect(http.StatusFound, c.Echo().Reverse(route, routeParams)) } +func (t *Controller) SetValidationErrorMessages(c echo.Context, err error, data interface{}) { + for _, ve := range err.(validator.ValidationErrors) { + var message string + + // Default the field label to the name of the struct field + label := ve.StructField() + + // Attempt to get a label from the field's struct tag + if field, ok := reflect.TypeOf(data).FieldByName(ve.Field()); ok { + if labelTag := field.Tag.Get("label"); labelTag != "" { + label = labelTag + } + } + + // Provide better error messages depending on the failed validation tag + switch ve.Tag() { + case "required": + message = "%s is required." + default: + message = "%s is not a valid value." + } + + msg.Danger(c, fmt.Sprintf(message, label)) + } +} + // getTemplatesDirectoryPath gets the templates directory path // This is needed incase this is called from a package outside of main, // such as testing diff --git a/routes/login.go b/routes/login.go index e418fea..bfb99a5 100644 --- a/routes/login.go +++ b/routes/login.go @@ -19,8 +19,8 @@ type ( } LoginForm struct { - Username string `form:"username" validate:"required"` - Password string `form:"password" validate:"required"` + Username string `form:"username" validate:"required" label:"Username"` + Password string `form:"password" validate:"required" label:"Password"` } ) @@ -47,7 +47,7 @@ func (l *Login) Post(c echo.Context) error { // Validate the form if err := c.Validate(l.form); err != nil { - msg.Danger(c, "All fields are required.") + l.SetValidationErrorMessages(c, err, l.form) return l.Get(c) }