Search code examples
grailsgrails-ormgrails-2.0

command object validation strange behaviour


I have the following command class:

class BookmakerCommand {
    Bookmaker bookmaker
    CommonsMultipartFile logotype

        logotype validator: { val, obj ->
            def logoImage = ImageIO.read(val.getInputStream())
            if (logoImage.width > 500 || logoImage.height > 500) {
                obj.errors.reject('logotype.invalid', 'bookmaker.logo.invalid.format')
            }
        }
}

where logotype is an image. As you can see in case if width or height has invalid size logotype field should be rejected. I want this error to appear in top of the page and using such construction for this purpose:

    <g:hasErrors bean="${command}">
        <ul class="errors" role="alert">
            <g:eachError bean="${command}" var="error">
                <li <g:if test="${error in org.springframework.validation.FieldError}">data-field-id="${error.field}"</g:if>><g:message error="${error}"/></li>
            </g:eachError>
        </ul>
    </g:hasErrors>

In case if some of bookmaker's fields is not valid this construction shows corresponding errors but it doesn't when logotype is not valid. I tried to debug and found out that this line:

obj.errors.reject('logotype.invalid', 'bookmaker.logo.invalid.format')

actually doesn't add error to command object because errors still have 0 size. What I'm doing wrong? Thank you!

UPDATE:

I debuged one more time and found out that I was not completely right about this line:

obj.errors.reject('logotype.invalid', 'bookmaker.logo.invalid.format')

debugging within the validator code shows that this line adds the corresponding error to command object but error dissapears just after exiting validator code and going to back to controller. So I start debugging from this piece of code:

   if (!command.validate()) {
       ...
      }

debug goes to validator code:

logotype validator: { val, obj ->
                def logoImage = ImageIO.read(val.getInputStream())
                if (logoImage.width > 500 || logoImage.height > 500) {
                    obj.errors.reject('logotype.invalid', 'bookmaker.logo.invalid.format')
                }
            }

after that obj (which is command object) contains error ('bookmaker.logo.invalid.format') but when debug continues and goes to

   if (!command.validate()) {
       >> HERE
      }

command.errors becomes empty again. Very strange :-(


Solution

  • I think, you shouldn't call errors.reject() in your validator. Instead, you must return false or error code:

    logotype validator: { val, obj ->
       def logoImage = ImageIO.read(val.getInputStream())
       logoImage.width > 500 || logoImage.height > 500 ? 'bookmaker.logo.invalid.format' : true
    }