Лучше вернуть 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's Box[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.

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