Validation and Validation Errors in Service Layer

I learned from the latest Java developments that throw RuntimeException

and handle it in aspect oriented ways - this is the current trend of error handling at the service level. This means that if something goes wrong, you just quit RuntimeException

or even better, let Bean Validation do the magic.

Advantage: you don't clutter your code with checks try-catch

and if(entity.getName() == nil)

. Everything is checked in the background, making your code more readable.

So I'm wondering how would this be done in Grails? Of course, if I use .save(failOnError:true)

, I get nice ValidationException

. But that leads to a very nasty default error page that doesn't improve the usability of the web application at all.

Should I put it in a block try-catch

at the controller level? Let's say it EntityService

has a method that looks like this:

def toggleSomething(String entityId) = {
    if(!someOtherPrerequisite) {
        throw new EntityException("SomeOtherPrerequisite was not satisfied") // extends RuntimeException
    }

    Entity entity = Entity.get(entityId)
    entity.someProperty = somePropertyValue
    entity.save(failOnError:true) // throws a ValidationException
}

      

Then the controller will call it like this:

def toggle = {
    try {
        entityService.toggleSomething(params.id)
    }
    catch(e) {
        flashHelper.error 'I'm sorry, something went wrong.'
    }
}

      

But it seems to be a pretty old school, when Grils is so new school in so many things. Isn't there a way to do it a RuntimeExceptions

little better without clogging up the code with help try-catch

?

+3


source to share


1 answer


The pattern I am following is the following:

  • If errors can be wrapped within the Grails domain, then don't go directly to exception handling. If your service method is mostly about your grails domains, then when an error occurs, they are terminated in the domain.errors collection. In the controller, just check for these errors (hasErrors ()). Since RuntimeException is still thrown under the covers, your transaction is rolled back, no harm, no foul.

  • If you are dealing with a third party library (maybe an external webservice or such), don't be afraid of exceptions. Just because Grails (Groovy) doesn't require any processing from you, they are still good to use / use.

  • Sometimes none of the above applies and perhaps your service method should just return some kind of true or false flag as a result of some logic. To take your example for example:

Service

    def toggleSomething(String entityId) = {
        if(!someOtherPrerequisite) {
            return false
        }
    }

        Entity entity = Entity.get(entityId)
        entity.someProperty = somePropertyValue
        entity.save() // throws a ValidationException
        return entity.hasErrors()
    }

      



controller

    def toggle = {
        if (!entityService.toggleSomething(params.id)) {
            flashHelper.error 'I'm sorry, something went wrong.'
        }
    }

      

Unfortunately, there is probably no hard or wrong way to approach this. So expect different answers than mine.

+2


source







All Articles