Является ли хорошей практикой отлавливать множество конкретных исключений вместе с одним общим универсальным исключением? - PullRequest
0 голосов
/ 29 октября 2018

Общая проблема

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

Например, может быть полезно скрыть детали ошибок в классе DAO, выдав универсальный DaoException. Таким образом, клиенты не должны знать, читаете ли вы из файла, веб-службы или реляционной базы данных. Но допустим, что вы проверяете пользовательский ввод, и есть по крайней мере четыре вещи, которые могут пойти не так с пользовательским вводом. Разве не разумнее в последнем случае выбросить четыре разных исключения, по одному для каждой вещи, которая пошла не так с проверкой?

Моя конкретная проблема

В моем текущем проекте я работаю над сервисным методом, который сохраняет древовидную структуру в реляционной базе данных. Оно должно проверять дерево, и есть как минимум четыре вещи, которые могут быть неверны с деревом. Может быть дублированный узел или узел может не иметь своих обязательных полей X, Y, Z. Таким образом, для сервисного метода имеет смысл выдать четыре разных исключения: DuplicateNodeException, MissingXException, MissingYException, MissingZException.

Но метод обслуживания также использует класс DAO, который выбрасывает DataAccessException через JdbcTemplate. Я хотел бы знать, как справиться с этим DataAccessException. Имеет ли смысл обернуть его как ManagerException, а затем снова как ServiceException и обработать его как ServiceException? Тогда я бы смешал оба подхода: (а) выбрасывать особые описательные исключения и (б) генерировать исключения исключительной оболочки. Это хорошая идея, чтобы смешать эти подходы здесь?

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

Возможное решение (согласно ответу Андреаса)

Имеет ли смысл обрабатывать подобные исключения в моем классе обслуживания? Ниже приведен псевдокод, представляющий возможное решение. Таким образом, я не создаю бесполезную, проверенную, неописуемую исключительную ситуацию ServiceException, но у меня есть универсальное средство для непроверенных исключений (перехватывая исключение в конце). Что вы думаете об этом решении?

class HttpService {

    private Service service;

    // ...

    public HttpServiceResponse saveTree(Node root) {
        try {
            service.saveTree(root);  
        } catch (DuplicateNodeException e) {
            return HttpServiceResponse.failure(DUPLICATE_NODE_EXCEPTION);
        } catch (MissingXException e) {
            return HttpServiceResponse.failure(MISSING_X_EXCEPTION);
        } catch (MissingYException e) {
            return HttpServiceResponse.failure(MISSING_Y_EXCEPTION);
        } catch (MissingZException e) {
            return HttpServiceResponse.failure(MISSING_Z_EXCEPTION);
        } catch (Exception e) {
            return HttpServiceResponse.failure(INTERNAL_SERVER_ERROR);
        }
    }
}

1 Ответ

0 голосов
/ 29 октября 2018

Большинство исключений должно быть не проверено , потому что они на самом деле не действуют, т. Е. На самом деле вызывающий не может ничего с этим поделать, кроме как передать его или зарегистрировать его и выполнить любую операцию, которая в данный момент выполняется. прогресс. Следует проверять только те исключения, которые являются действующими и требуют таких действий вызывающего абонента, что довольно редко.

Если все исключения сняты, это означает, что вызывающая сторона может сделать с одним универсальным вызовом. Поскольку сервисному уровню больше не нужно обертывать исключения, например, из На уровне DAO вызывающая сторона может перехватывать и обрабатывать определенные исключения, если это необходимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...