Search code examples
grailsgrails3

How to customize error messages in Grails 3.3?


In GRAILS it is possible to define generic erros in the i18n/messages.properties in the way

default.invalid.validator.message=Property [{0}] of class [{1}] with value [{2}] does not pass custom validation

And with the hasErrors method in GSP files the errors are shown like

Property [eyeColor] of [class org.application.PersonData] with value [brown] does not pass custom validation

Is it possible to define anywhere a translation for "property" and "class" name so error can be shown in a frienly? something like

Property [eye color] of [user] with value [brown] does not pass custom validation

Something like setting in the i18n/messages.properties file

org.application.PersonData=user
org.application.PersonData.eyeColor=eye color

Solution

  • Is it possible to define anywhere a translation for "property" and "class" name so error can be shown in a frienly? something like

    Yes. You can make the error message whatever you want.

    See the project at https://github.com/jeffbrown/geblini18nmessages.

    https://github.com/jeffbrown/geblini18nmessages/blob/94ac5402782e4dbf10f3822cecf6857ba7451096/grails-app/domain/geblini18nmessages/PersonData.groovy

    package geblini18nmessages
    
    class PersonData {
        String name
        String eyeColor
        static constraints = {
            eyeColor validator: { val ->
                // valid
                if(val in ['blue', 'green', 'brown']) return true
    
                // invalid
                return ['personData.eye.color.invalid', val]
            }
        }
    }
    

    https://github.com/jeffbrown/geblini18nmessages/blob/94ac5402782e4dbf10f3822cecf6857ba7451096/grails-app/i18n/geblin.properties

    personData.eye.color.invalid=Eye color with value [{2}] does not pass custom validation
    

    When validation fails, that custom validator is returning a List. The first element in that List represents the message key that will be used to lookup the validation error message. Every subsequent element in the List may be any arbitrary values that you want to put into the message. In the message you can have variables like {2}, {3} etc. that get substituted with values in the List. {0} is the name of the property being validated. {1} is the name of the domain class. {2} and each subsequent index above that will correspond to values you put in the List after the message code.

    The message you showed ("Property [eye color] of [user] with value [brown] does not pass custom validation") could be achieved by definin the property like this:

    personData.eye.color.invalid=Property [eye color] of [user] with value [{2}] does not pass custom validation.
    

    It doesn't make sense to use parameters for "eye color" and "user" in this case because the error message is only used for a particular property in a particular domain.

    More info at https://docs.grails.org/4.0.5/ref/Constraints/validator.html.