Лучше вернуть None или выбросить исключение при получении URL-адреса?

У меня есть вспомогательный метод Scala, который в настоящее время пытается получить URL-адрес и вернуть опцию[String] с HTML этой веб-страницы.

Если есть какие-либо исключения (искаженный url, тайм-ауты чтения и т. д...) или если есть какие-либо проблемы, он возвращает None. Вопрос в том, было бы лучше просто выбросить исключение, чтобы вызывающий код мог регистрировать исключение или предпочтительнее вернуть None в этом случае?

3 ответов


создание исключений дорого, потому что трассировка стека должен быть заполнен. Бросать и ловить исключения также дороже, чем обычный возврат. Учитывая это, вы можете задать себе следующие вопросы:--26-->

  • вы хотите принудительно обработать ошибку вызывающим абонентом? если это так, не бросайте исключение, так как Scala не имеет механизма checked-exception, который заставляет вызывающего абонента ловить их.

  • в случае ошибки, вы хотите включить подробную информацию о том, почему это не удалось? если нет, вы можете просто вернуть Option[A], где A ваш тип возврата, и тогда ты либо Some(validContent) или None, без дополнительных объяснений. Если да, вы можете вернуть что-то вроде Either[E, A] или Scalaz Validation[E, A]. Все эти параметры заставляют вызывающего абонента как-то разворачивать результат, будучи свободным для обработки ошибки E как он хочет. А теперь что E быть?

  • вы хотите предоставить трассировку стека в случае неудачи? если да, то ты мог бы возвращение Either[Exception, A] или Validation[Exception, A]. Если вы действительно идете с исключением, вы захотите использовать Try[A], два возможных случая которых Failure(exc: Throwable) и Success(value: A). Обратите внимание, что вы, конечно, понесете расходы на создание throwable. Если нет, вы можете просто вернуть Either[String, A] (и будьте очень осторожны, чтобы помнить, является ли Right означает успех или неудача здесь - Left обычно используется для ошибок, и Right для "правильных" стоимостью Validation возможно, понятнее). Если вы хотите дополнительно верните трассировку стека, вы можете использовать Lift's Box[A], что может быть Full(validContents), Empty без дополнительного объяснения (очень похоже на Option[A] здесь), или указать Failure который может хранить строку ошибки и / или throwable (и многое другое).

  • возможно, вы хотите предоставить несколько почему он провалился? затем вернуться Either[Seq[String], A]. Если вы делаете это часто, вы, вероятно, хотите использовать Scalaz и Validation[NonEmptyList[String], A] вместо этого, который предоставляет некоторые другие приятные вкусности. Посмотрите его для получения дополнительной информации об этом или проверьте эти примеры использование.


Я думаю, что в этом случае, если важно регистрировать исключения, то непременно бросьте исключения (и, возможно, просто верните строку вместо опции). В противном случае вы можете просто вернуть никто. Одно предупреждение - могут быть исключения по другим причинам, которые вы не предвидите, и в этом случае может быть опасно сделать весь бит кода.

одна вещь, которую вы могли бы сделать, это что-то вроде лифта


общее эмпирическое правило: "если вы можете обработать исключение, обработайте его". Так что не хватает контекста, чтобы догадаться. Можно использовать пару методов tryFetchUrl/fetchUrl.