2012-03-18 7 views
3

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

Преимущество: вы не засовываете свой код 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?

ответ

2

Узор Я следую за это:

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

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

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

Сервис

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.' 
     } 
    } 

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

+0

спасибо. Я прочитал еще несколько статей и сделал это похожим на ваш пример кода, но я возвращаю объект с ошибкой в ​​службу. Просто вернусь, если у него есть ошибки вообще, поскольку логическое значение - отличная идея, и во многих случаях этого будет достаточно. –

+0

Не стесняйтесь принять это как ответ. ;) – Gregg

+0

Правда, я ждал еще нескольких входных данных, но мне кажется, что вы единственный гуру Grails здесь, на SO. ;) –

Смежные вопросы