Чи повинен службовий рівень охоплювати всі винятки дао та обробляти їх як службові виключення?


23

У мене є тришаровий веб-додаток Spring: дао, сервіс та контролери. Контролер ніколи не викликає безпосередньо дао, він робить це через рівень обслуговування. Зараз більшу частину часу, якщо існує виключення дао (час виконання), яке не обробляється, буде сприйняте JSP, що показує повідомлення про помилку кінцевому користувачеві. Чи повинен службовий рівень охоплювати всі винятки дао та обробляти їх як службові виключення?

try {
   daoInstance.someDaoMethod();
} catch(DataAccessException dae) {
   throw new ServiceException("message", dae);
}

Припустимо, ServiceException також є часом виконання, і з ним також не обробляється. Чи є різниця просто кинути DataAccessException замість ServiceException? Я просто подумав, що презентаційний шар не повинен знати про виняток доступу до даних. Але я не бачу сенсу ловити непоодинокі винятки лише для того, щоб їх завершити.

Відповіді:


18

Я думаю, що важливим фактором є те, хто є вашими клієнтами послуг.

Якщо ваш сервісний рівень є лише архітектурною межею між шарами у вашому власному проекті, а клієнт сервісу знаходиться в межах однієї сфери довіри, тоді це нормально, щоб розслабитися, і нехай вивірені винятки пускаються на рівень контролера або на клієнт сервісу.

Однак для публічного коду; сервіс, який споживається третьою стороною або замовником, я вважаю, що більш чітко перекривати будь-які неперевірені винятки з винятком, орієнтованим на сервіс, в першу чергу, з точки зору безпеки, по-друге, для вільного з’єднання та чистої абстракції.

Виняток з рівня даних ніколи не повинен прямо робити це аж до кінцевого користувача веб-програми . Він потенційно містить внутрішню інформацію про вашу схему, ваші запити, інформацію про номер рядка, назви змінних чи функцій тощо. Виключення кінцевого користувача можуть бути захищені в безпечному режимі.

Зовнішній клієнт служби не переймається деталізацією вашої реалізації, і в будь-якому випадку не може впоратися з неперевіреними винятками, оскільки це проблеми або екологічні проблеми. У захищених програмах помилки бази даних просто недостатньо безпечні для розповсюдження, OracleException - ORA-01234 - ...що може бути третьою таблицею, яка була вставлена. Клієнту слід дозволити вирішувати будь-які перевірені / очікувані винятки, з якими він може працювати, та розглянути все інше як потенційний звіт про помилку. Ваш контракт на обслуговування має бути атомною, послідовною, транзакційною абстракцією. Якщо він не може нічого зробити стосовно винятку, то єдине корисне, що залишилося, - це надати вам повідомлення про помилку. Ви вже маєте можливість реєструвати винятки, тож навіщо обтяжувати свого кінцевого користувача деталями? Ваш додаток може контролюватися, щоб ви вже знали про неперевірені винятки, перш ніж користувачі повідомлять про них.

Ніколи не нормально їсти винятки, і я не прихильник перевірених винятків, але я вважаю за краще скласти план, що відповідає природі загального продукту.


13

Ні, ви не повинні містити винятки DAO у веб-програмі

У коді багато шуму за нульової вигоди. Винятки DAO - це неперевірені винятки з поважної причини. Код програми не може зробити нічого корисного для відновлення після виключення DAO. Справжня проблема тут:

... його спіймає JSP, який показує кінцевому користувачу повідомлення про помилку.

Вирішіть цю проблему в одному місці замість того, щоб збігати всю базу коду.

Ви керуєте тим, як відображається невиконаний виняток для користувача. Невиконані винятки пов’язані з помилками програми або збою в базовій системі. Немає підстав надавати користувачеві будь-яку інформацію про причину, по якій його запит не може бути наданий. Користувач нічого не може зробити. Все, що вам потрібно зробити, - це надрукувати дружню сторінку про помилки.

NB: Якщо ви виявите, що ви пишете багато втомливого коду, наприклад, створивши купу блоків лову, які просто загортають і перекидають, майже завжди є краще рішення.


Дякую за вашу відповідь. І так, jsp показує користувацьке повідомлення: "На жаль, щось пішло не так". Тут не відображається жодна інформація про виняток
Оскар

7

Основна причина, з якої можна використовувати обгортання винятків, - це запобігання коду в бізнес-шарі від необхідності знати про всі можливі винятки в системі . Для цього є дві основні причини:

  • Послідовність: оголошені винятки сукупно спрямовані до вершини стека викликів. Якщо ви не переховуєте винятки, а замість цього передаєте їх, оголошуючи свої методи, щоб кинути їх, ви можете отримати методи верхнього рівня, які оголошують багато різних винятків. Оголошення всіх цих винятків у кожному методі резервного копіювання стека викликів стає стомлюючим.

  • Інкапсуляція: Ви, можливо, не хочете, щоб компоненти верхнього рівня нічого не знали про компоненти нижнього рівня, ні про винятки, які вони викидають. Наприклад, мета інтерфейсів і реалізацій DAO полягає в абстрагуванні деталей доступу до даних подалі від решти програми. Тепер, якщо ваші методи DAO кидають SQLException, тоді код, використовуючи DAO, повинен буде їх наздогнати. Що робити, якщо ви переходите на реалізацію, яка зчитує дані з веб-служби замість бази даних? Тоді вам, методам DAO, доведеться кидати і RemoteException, і SQLException. Якщо у вас є DAO, який читає дані з файлу, вам також потрібно буде кинути IOException. Це три різні винятки, кожен з яких пов'язаний із власною реалізацією DAO.

Отже, коротше, відповідь - так!


3
Реалізації JPA (наприклад, у сплячому режимі) містять неперевірені винятки. Їх не потрібно оголошувати чи спіймати.
кевін клайн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.