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

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

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


person James    schedule 31.07.2011    source источник
comment
Если это вспомогательный метод, я предполагаю, что он частный. Если это личное, то вы звоните. Если вы звоните, то у вас есть вся информация о том, что должно произойти, так что делайте, что хотите. В противном случае см. ответ Жана.   -  person agilesteel    schedule 31.07.2011


Ответы (3)


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

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

  • В случае ошибки, хотите ли вы указать причину сбоя? Если нет, вы можете просто вернуть 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). Обратите внимание, что вы, конечно, понесете расходы на создание метательного объекта. Если нет, вы можете просто вернуть Either[String, A] (и будьте особенно внимательны, чтобы помнить, означает ли Right успех или неудачу здесь — Left обычно используется для ошибок, а Right для «правильного» значения — Validation может быть понятнее). Если вы хотите опционально вернуть трассировку стека, вы можете использовать Box[A] Lift, который может быть Full(validContents), Empty без дополнительных пояснений (очень похоже на Option[A] до сих пор), или указать Failure, который может хранить строка ошибки и/или бросок (и многое другое).

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

person Jean-Philippe Pellet    schedule 31.07.2011
comment
Отличное резюме! Лично я большую часть времени использую Либо [String,...] , хотя проверка Scalaz кажется более понятной. - person Zdenek F; 31.07.2011

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

Одна вещь, которую вы могли бы сделать, это что-то вроде системы Box от Lift. Коробка, по сути, является опцией, но с парой добавленных функций: Full похожа на Some, Empty похожа на None, но Lift идет еще дальше и имеет Failure, которая похожа на Empty, но с причиной/ сообщение.

person Dylan    schedule 31.07.2011

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

person Grozz    schedule 31.07.2011