Лучше вернуть None или сгенерировать исключение при получении URL? - PullRequest
13 голосов
/ 31 июля 2011

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

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

Ответы [ 3 ]

32 голосов
/ 31 июля 2011

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

  • Вы хотите принудительно обработать ошибку вызывающей стороной? Если это так, не бросайтеисключение, поскольку в 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], что дает некоторые другие приятные плюсы.Посмотрите его для получения дополнительной информации или посмотрите эти примеры использования .

1 голос
/ 31 июля 2011

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

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

0 голосов
/ 31 июля 2011

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

...