Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go "go-playground/validator/v10": how to register a custom error message

Tags:

validation

go

I use github.com/go-playground/validator/v10.

I create a custom validator (stringMinLength) that verifies that a string is longer than a given length. If the length of the string to validate is shorter than the given minimum allowed length, then I want to set an error message that describes the problem.

Below, my code:

package main

import (
    "fmt"
    "github.com/go-playground/validator/v10"
    "strconv"
    "unicode/utf8"
)

type Profile struct {
    Name string `validate:"required,stringMinLength=3"`
    Age  uint   `validate:"required,gt=10"`
}

// See https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Custom_Validation_Functions
func stringMinLength(inField validator.FieldLevel) bool {
    //var value string = inField.Field().String()
    value, kind, nullable := inField.ExtractType(inField.Field())
    param := inField.Param()

    fmt.Printf("=> name: [%s]\n", inField.FieldName())
    fmt.Printf("=> tag: [%s]\n", inField.GetTag())
    fmt.Printf("=> struct field name: [%s]\n", inField.StructFieldName())
    fmt.Printf("=> param: [%s]\n", param)
    fmt.Printf("=> value: [%s]\n", value.String())
    fmt.Printf("=> kind: [%s]\n", kind.String())
    if nullable {
        fmt.Printf("=> nullable: true\n")
    } else {
        fmt.Printf("=> nullable: false\n")
    }

    // The parameter must be an integer!
    minLength, err := strconv.ParseUint(param, 10, 32)
    if err != nil {
        panic(fmt.Sprintf(`stringMinLength parameter must be an unsigned integer! (got "%s" instead)`, param))
    }

    status := uint64(utf8.RuneCountInString(value.String())) >= minLength
    if !status {
        // I want to register an error message that informs the caller that the given name is too short
    }

    return status
}

func main() {

    myValidator := validator.New()
    if err := myValidator.RegisterValidation("stringMinLength", stringMinLength); err != nil {
        panic(err)
    }

    // ===================================================
    // Test SUCCESS
    // ===================================================

    profile := Profile{
        Name: "Joe",
        Age:  25,
    }

    if err := myValidator.Struct(profile); err != nil {
        panic(err)
    }

    fmt.Printf("SUCCESS (as expected) => OK\n")

    // ===================================================
    // Test FAILURE
    // ===================================================

    profile = Profile{
        Name: "IT",
        Age:  9,
    }

    if err := myValidator.Struct(profile); err != nil {
        fmt.Printf("FAILURE (as expected) => OK\n")

        fmt.Printf("err: %T\n", err) // => validator.ValidationErrors
        errors := err.(validator.ValidationErrors)
        for _, v := range errors {
            fmt.Printf("%s\n", v.Error())
        }
    }
}

You can test it here: https://go.dev/play/p/Ol6sq8hAyjq

Question: how do I return an error message from my custom validator (stringMinLength) ?

I have read information about "translators," but I don't see how translators fit into the problem.

like image 723
Denis Beurive Avatar asked Jan 18 '26 00:01

Denis Beurive


1 Answers

It seems that what I need to do is not possible right now:

https://github.com/go-playground/validator/issues/669

The functionality will be added to version 11:

https://github.com/go-playground/validator/issues?q=is%3Aissue+is%3Aopen+label%3Av11

like image 112
Denis Beurive Avatar answered Jan 20 '26 20:01

Denis Beurive