ValidationException errors in errors

1.4k Views Asked by At

In grails 2.3, I want to send customized error message by JSON. But when I use

class ApiError {
    String message
    String status
    Exception error
}

and try to parse it as JSON I get: (I ommit irrevelant message and status)

"error": {
    "cause": null
    "class": "grails.validation.ValidationException"
    "errors": {
        "errors": [1]
        0:  {
            "object": "com.example.Firm"
            "field": "context"
            "rejected-value": null
            "message": "Property [context] of class [class com.example.Firm] cannot be null"
        }
    }
    "localizedMessage": "Firm is not valid: - Field error in object 'com.example.Firm' on field 'context': rejected value [null]; codes [com.example.Firm.context.nullable.error.com.example.Firm.context,com.example.Firm.context.nullable.error.context,com.example.Firm.context.nullable.error.java.lang.String,com.example.Firm.context.nullable.error,firm.context.nullable.error.com.example.Firm.context,firm.context.nullable.error.context,firm.context.nullable.error.java.lang.String,firm.context.nullable.error,com.example.Firm.context.nullable.com.example.Firm.context,com.example.Firm.context.nullable.context,com.example.Firm.context.nullable.java.lang.String,com.example.Firm.context.nullable,firm.context.nullable.com.example.Firm.context,firm.context.nullable.context,firm.context.nullable.java.lang.String,firm.context.nullable,nullable.com.example.Firm.context,nullable.context,nullable.java.lang.String,nullable]; arguments [context,class com.example.Firm]; default message [Property [{0}] of class [{1}] cannot be null] "
    "message": "firm is not valid: - Field error in object 'com.example.Firm' on field 'context': rejected value [null]; codes [com.example.Firm.context.nullable.error.com.example.Firm.context,com.example.Firm.context.nullable.error.context,com.example.Firm.context.nullable.error.java.lang.String,com.example.Firm.context.nullable.error,firm.context.nullable.error.com.example.Firm.context,firm.context.nullable.error.context,firm.context.nullable.error.java.lang.String,firm.context.nullable.error,com.example.Firm.context.nullable.com.example.Firm.context,com.example.Firm.context.nullable.context,com.example.Firm.context.nullable.java.lang.String,com.example.Firm.context.nullable,firm.context.nullable.com.example.Firm.context,firm.context.nullable.context,firm.context.nullable.java.lang.String,firm.context.nullable,nullable.com.example.Firm.context,nullable.context,nullable.java.lang.String,nullable]; arguments [context,class com.example.Firm]; default message [Property [{0}] of class [{1}] cannot be null] "
    "stackTrace": [...143]
    "suppressed": [0]
}

I do not understand; what's the point of using errors array in errors? And how to get only one errors array? Here is a source code of this class.

1

There are 1 best solutions below

0
On

Grails validation errors contain both global errors and field errors. Whenever validation exception occurs in grails, it doesn't throw a new exception for each field error, rather it wraps all field errors inside a single Error object. There may be global object errors, a global reason for rejecting an object.

So if you want to avoid errors inside errors then you should modify your ApiError class by replacing Exception error with List<Errors> errors and setting its value from instance.errors.

Or you can use a custom method to parse errors: CodecLookup codecLookup

protected List retrieveErrors(instance) {

    CodecLookup codec = Holders.applicationContext.getBean(CodecLookup)

    List errors = []
    g.eachError([bean: instance], {
        error ->
            errors.add(codec.lookupDecoder('HTML').decode(g.message(error: error)))
    })

    return errors
}

g is the namespace for ValidationTagLib that is available in each controller.