Множественная конкретная добыча или одна ловит все?

Я видел, как эта тема иногда возникала в прошлом, но даже после того, как Googling об этом , я до сих пор не могу понять, что было бы хорошим и элегантным способом иметь дело с этим, Итак, вот и все.

Скажем, у меня есть некоторый код, который выдает различные исключения ...

try {
  /* some code that throws these exceptions */
} catch (NoSuchAuthorityCodeException e) {
    throw new MyAPIException("Something went wrong", e);
} catch (FactoryException e) {
    throw new MyAPIException("Something went wrong", e);
} catch (MismatchedDimensionException e) {
    throw new MyAPIException("Something went wrong", e);
} catch (TransformException e) {
    throw new MyAPIException("Something went wrong", e);
}

... и, как мы можем видеть, я просто обертываю эти исключения и выкидываю новый, говоря, что что-то пошло не так в моем API

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

try {
  /* some code that throws these exceptions */
} catch (Exception e) {
    throw new MyAPIException("Something went wrong", e);
}

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

try {
  /* some code that throws some exceptions */
} catch (RuntimeException e) {
    throw e;
} catch (Exception e) {
    throw new MyAPIException("Something went wrong", e);
}

Это немного громоздко, но это помогает. Теперь есть еще одна небольшая проблема, связанная с перехватом (исключение e), что если мой внутренний API генерирует другое MyAPIException, оно также будет перехвачено, упаковано и выброшено в другом MyAPIException. В этом конкретном случае мы могли бы также поймать MyAPIException и перезапустить его.

try {
  /* some code that throws some exceptions */
} catch (RuntimeException e) {
    throw e;
} catch (MyAPIException e) {
    throw e;
} catch (Exception e) {
    throw new MyAPIException("Something went wrong", e);
}

Хорошо, это снова становится грязным, но в этом случае мы предотвращаем обертывание MyAPIException и просто перекидываем его. Но есть еще одна проблема с блоком catch (Exception e), заключающаяся в том, что если внутренний API изменяется и начинает выдавать другое исключение (некоторые, кроме этих 4, упомянутых выше), компилятор ничего не скажет по этому поводу, и мы не будем Понятия не имею. Не то чтобы это было серьезной проблемой, поскольку, вероятно, я бы отнесся к этому таким же образом.

С этим сценарием, я думаю, вопрос в том, какой из них лучше и есть ли лучшие варианты?

7
задан Pablo Cabrera 31 August 2010 в 12:04
поделиться

1 ответ

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

Кроме того, вы не можете зафиксировать ни простой, ни множественный захват. Это скорее субъективное решение IMO, так как есть исключения, которые являются фатальными (так как вся программа должна останавливаться) для более простых в обращении типов.

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

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

Наконец, если вы чувствуете, что иметь слишком много пользовательских исключений — горький выбор, вы можете иметь одно единственное исключение с четко задокументированными кодами ошибок.Таким образом, вызывающий объект может обрабатывать исключение и обрабатывать коды ошибок по своему усмотрению.

2
ответ дан 7 December 2019 в 01:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: