Ошибки валидации и валидации на уровне сервиса - PullRequest
3 голосов
/ 19 марта 2012

Из последних разработок Java я узнал, что использование RuntimeException и обработка его аспектно-ориентированными способами является современной тенденцией в обработке ошибок на сервисном уровне.Это означает, что если что-то пойдет не так, вы просто выбрасываете RuntimeException или даже лучше, пусть Bean Validation сделает волшебство.

Преимущество в том, что вы не засоряете свой код с помощью try-catch и if(entity.getName() == nil) проверок.Все проверяется в фоновом режиме, что делает ваш код более читабельным.

Так что мне интересно, как это будет сделано в Grails?Конечно, если я использую .save(failOnError:true), я получаю хороший ValidationException.Но это приводит к очень неприятной странице ошибок по умолчанию, которая совсем не улучшает удобство использования веб-приложения.

Нужно ли мне помещать ее в блок try-catch на уровне контроллера?Допустим, у EntityService есть метод, который выглядит следующим образом:

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
}

Тогда контроллер будет вызывать его так:

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

Но это выглядит довольно старымшкола, когда Grails - новая школа во многих вещах.Разве нет способа обработать RuntimeExceptions немного лучше, не засоряя код с помощью try-catch?

1 Ответ

2 голосов
/ 19 марта 2012

Шаблон, который я придерживаюсь:

  1. Если ошибки могут быть помещены в домен Grails, то не занимайтесь напрямую обработкой исключений.Если ваш метод обслуживания в основном работает с вашими доменами Grails, то при возникновении ошибки они попадают в коллекцию domain.errors.В контроллере просто проверьте эти ошибки (hasErrors ()).Поскольку под прикрытием в любом случае создается исключение RuntimeException, ваша транзакция откатывается, без вреда, без фола.

  2. Если вы имеете дело со сторонней библиотекой (возможно, внешним веб-сервисом)или такой) тогда не бойтесь исключений.Просто потому, что Grails (Groovy) не требует, чтобы вы с ними обрабатывали, они все равно хороши для использования / использования.

  3. Иногда ни один из вышеперечисленных не применим, и, возможно, ваш метод обслуживания должен просто вернутьсянекоторый флаг true или false относительно результата некоторой логики.Возьмем, к примеру, ваш пример:

Сервис

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

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

Контроллер

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

К сожалению, вероятно, нет ни одного правильного или неправильного утвержденияспособ подойти к этому.Поэтому ожидайте ответов, отличных от моих.

...