Обернутое исключение из компонента

Есть такая система исключений, при которой компонент выдает исключение для конкретного компонента. Например, все классы доступа к данным выбрасывают DataAccessException.

В этом стиле мне часто приходится перехватывать и повторно генерировать исключение для конкретного компонента, потому что вызываемые методы помечены как throws Exception:

try {
    int foo = foo();
    if (foo != expectedValue) {
        throw new ComponentException("bad result from foo(): " + foo);
    }
    bar();
}
catch (ComponentException e) { 
    throw e; 
}
catch (Exception e) { 
    throw new ComponentException(e); 
}

Вы делаете то же самое? Вы находите это уродливым?

Этот вопрос касается не действительности этого стиля, а чего-то в рамках ограничений этого стиля.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
263
2

Ответы 2

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

try {
  componentCall();
} catch (ComponentException e) {
  Throwable t = e.getCause();
  //Handle each possible cause
}

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

Учитывая, что вы ограничены в его использовании, я бы, по крайней мере, попытался избежать выброса ComponentException как с причиной, так и без нее, что делает его более запутанным, чем должно быть, в вашем примере я бы добавил InvalidFooException и добавил его как причина общего ComponentException.

try {
    int foo = foo();
    if (foo != expectedValue) {
        throw new InvalidFooException("bad result from foo(): " + foo);
    }
    bar();
}
catch (Exception e) { 
    throw new ComponentException(e); 
}

getCause () предназначен для цепочки исключений, которые связаны только причинно, а не семантически.

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

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

Что полезно, так это создать иерархия исключений для исключения того же типа в строках:

Если DataAccessException будет корнем, то у вас может быть, например, DataSourceUnavailableException, InvalidDataSourceException, InvalidDataException, а затем вы можете решить перехватить только одного из родителей (если действие одинаково) или перехватить каждое исключение отдельно.

Кстати, зачем вам это, чтобы так себя вести?

Вы комментируете стиль :-) Предположим, я вынужден следовать ему (когда-либо был в такой ситуации?). Собственно, речь идет о первом улове. Это не бесполезно, без него мы получаем ComponentException с другим ComponentException в качестве причины, что нежелательно.

Miserable Variable 16.10.2008 12:26

Как можно выбросить новое исключение ComponentException ("плохой результат от foo ():" + foo); выбросить ComponentException с ComponentException в качестве причины?

Vinko Vrsalovic 16.10.2008 12:35

Думаю, я коснулся ограничений, которые накладывает на вас стиль, а также упомянул, что считаю его уродливым

Vinko Vrsalovic 16.10.2008 12:36

О, я понял ... от улова не избавиться (Исключение e) {}

Vinko Vrsalovic 16.10.2008 12:38

спасибо, Винко. Я попробую InvalidFooException, но искать красоту в изначально ошибочном стиле может быть слишком сложно.

Miserable Variable 16.10.2008 13:19

Возможно, это было бы менее уродливо (если функция foo () является той, которая была объявлена ​​как вызывающая исключение):

int foo;
try {
    foo = foo();
}
catch (Exception e) { 
    throw new ComponentException(e); 
}
if (foo != expectedValue) {
    throw new ComponentException("bad result from foo(): " + foo);
}
bar();

Благодарю за ваш ответ. Проблема с этим подходом в том, что он становится очень многословным. На практике вызову foo предшествуют многие другие вызовы, и за ним следуют многие другие вызовы, и этот подход потребует отдельных блоков try для каждого случая, когда должно быть сгенерировано исключение ComponentException.

Miserable Variable 16.10.2008 13:17

Другие вопросы по теме