Лучше вернуть None или выдать исключение при получении URL?
У меня есть вспомогательный метод Scala, который в настоящее время пытается извлечь URL-адрес и вернуть Option[String] с HTML-кодом этой веб-страницы.
Если есть какие-либо исключения (неправильно сформированный URL, тайм-аут чтения и т. Д.) Или если есть какие-либо проблемы, он возвращает None. Вопрос в том, что лучше было бы просто выбросить исключение, чтобы вызывающий код мог записать в журнал исключение, или в этом случае предпочтительнее вернуть None?
3 ответа
Создание исключений стоит дорого, потому что трассировка стека должна быть заполнена. Бросать и ловить исключения также дороже, чем обычный возврат. Учитывая это, вы можете задать себе следующие вопросы:
Вы хотите, чтобы вызывающая сторона обработала ошибку? Если это так, не выбрасывайте исключение, так как в Scala отсутствует механизм с проверенными исключениями, который заставляет вызывающую их перехватывать.
В случае ошибки, хотите ли вы включить подробности о том, почему это не удалось? Если нет, вы можете просто вернуться
Option[A]
, гдеA
ваш тип возврата, и тогда у вас будетSome(validContent)
или жеNone
без дополнительных объяснений. Если да, вы можете вернуть что-то вродеEither[E, A]
или скалазValidation[E, A]
, Все эти параметры вынуждают вызывающую программу как-то распаковывать результат, в то же время позволяя обрабатывать ошибку.E
как он хочет. Теперь, что должноE
быть?Вы хотите обеспечить трассировку стека в случае сбоя? Если это так, вы могли бы вернуться
Either[Exception, A]
или жеValidation[Exception, A]
, Если вы действительно идете с исключением, вы захотите использоватьTry[A]
чьи два возможных случаяFailure(exc: Throwable)
а такжеSuccess(value: A)
, Обратите внимание, что вы, конечно, будете нести расходы на создание броска. Если нет, вы можете просто вернутьсяEither[String, A]
(и будьте особенно внимательны, чтобы запомнить,Right
означает успех или неудачу здесь -Left
обычно используется для ошибок, иRight
для "правильного" значения -Validation
может быть, яснее). Если вы хотите опционально вернуть трассировку стека, вы можете использовать Lift'sBox[A]
что может бытьFull(validContents)
,Empty
без дополнительных объяснений (очень похоже наOption[A]
до здесь), или укажитеFailure
который может хранить строку ошибки и / или метание (и многое другое).Возможно, вы хотите предоставить несколько указаний относительно того, почему это не удалось? Затем вернитесь
Either[Seq[String], A]
, Если вы делаете это часто, вы, возможно, захотите использовать Scalaz иValidation[NonEmptyList[String], A]
вместо этого, который обеспечивает некоторые другие хорошие лакомства. Посмотрите его для получения дополнительной информации или ознакомьтесь с этими примерами использования.
Я думаю, что в этом случае, если важно зарегистрировать исключения, во что бы то ни стало выкинуть исключения (и, возможно, просто вернуть String вместо опции). В противном случае вы могли бы просто вернуть None. Одно предупреждение - могут быть исключения по другим причинам, которые вы не предвидите, и в этом случае может быть опасно делать полный фрагмент кода.
Одна вещь, которую вы могли бы сделать, это что-то вроде лифта Box
система. Коробка по сути является Опцией, но с парой функций, добавленных в: Full
это как Some
, Empty
это как None
, но Лифт идет на шаг дальше и имеет Failure
, который похож на Empty
но с причиной / сообщением.
Общее правило: "Если вы можете обработать исключение, обработайте его". Поэтому не хватает контекста, чтобы угадать. Вы можете использовать пару методов tryFetchUrl/fetchUrl.