Пересмотр передового опыта по обработке исключений - PullRequest
1 голос
/ 11 марта 2011

У меня есть фрагмент кода, в котором я фиксирую все исключения и выкидываю одно общее исключение в конце.Примерно так:

try {
  // do something here
} catch (Whatever e) {
  throw new MyException(e.getMessage());
}

Этот вид моего определения функции выглядит чистым, то есть «myFunc throws MyException», но в то же время я теряю семантику того, что вызвало проблему.С другой стороны, если я просто выброшу все исключения, это сделает тело функции более чистым, но определение функции будет содержать 1-5 операторов throw.

Мой вопрос: что лучше? ... следуетЯ фиксирую все исключения, сохраняя определение функции чистым, или я должен выбросить все, сохраняя тело функции чистым?

ПРИМЕЧАНИЕ: второй подход также усложнит код обработки исключений для моей функции ...

Ответы [ 5 ]

4 голосов
/ 11 марта 2011

Нет ничего плохого в том, что функция выдает 10 различных типов исключений, если каждое исключение имеет смысл в контексте.

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

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

Нет "лучшего" подхода, это зависит от контекста и информации, которую вы должны иметь на верхнем уровне. И вам не нужно беспокоиться о том, чтобы тело или прототип функции были «чистыми», оба решения «чисты». Единственным важным фактором принятия решения является потребность в информации.

4 голосов
/ 11 марта 2011

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

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

Напротив, если вы принимаете идентификатор некоторогоВид, который не должен быть null, и кто-то передает в null, кажется вполне уместным счастливо передать NullPointerException, не оборачивая его.

3 голосов
/ 11 марта 2011

Зачем выбирать одно или другое?

try { /* doing useful work */ }
catch (Whatever t) { throw new MyException(t); }

, где MyException имеет конструктор, принимающий Throwable в качестве параметра.

В общем, я согласен с тем, что Krtek иТи Джей Краудер сказал;генерировать исключения, которые имеют смысл на уровне абстракции, с которым вы работаете, означает ли это, что вы перечисляете один тип исключения или десять.

0 голосов
/ 11 марта 2011

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

catch(SomeException ex) {
    throw new ClearerException("This is what specifically went wrong", ex);
}

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

0 голосов
/ 11 марта 2011

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

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

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

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