I have a controller action to serve my react front-end. It requires the validation messages in the special format:
@Transactional
@Post( uri = '{/id}', consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON )
HttpResponse save( @PathVariable @Nullable Long id, @Body Map body ){
def o = bindFromIdAndBody id, body
if( o.save( flush:true ) ){
log.info "version >> $o.version"
HttpResponse.ok o
}else{
log.info '-------------------------'
List errors = o.errors.fieldErrors.collect{ FieldError fe ->
fe.codes.findResult{ String c ->
messageSource.getMessage c, fe.arguments, null, Locale.default
} ?: fe.codes.last()
}
log.info "save failed for $o: $errors"
HttpResponse.badRequest( errors:errors )
}
}
When I call the action, I'm getting 400 Bad Request
in my client, but instead of { errors:[ {..}, {..}, {..} ]
style JSON, I see rather:
{
"message":"Validation Error(s) occurred during save() : Field error in object ... default message [Property [{0}] of class [{1}] cannot be blank]\r\n",
"path":"fullName",
"_links":{"self":{"href":"/person/42","templated":false}}
}
Also the else{}
block is never reached, I don't get any further logs.
Any hints?
It appears, that in GORM configuration for Micronaut done via
compile 'io.micronaut.configuration:micronaut-hibernate-gorm'
the failOnError
is set to true
by default. That led to ValidationException
being thrown on save()
instead of populating o.errors
.
To fix the issue I added the line
grails.gorm.failOnError: false
to my application.yml
and now it's working like charm.