Я новичок в Scala, немного запутавшись в различных способах обработки исключений и поиска лучших советов по этой теме. Я пишу простой метод для извлечения Клиента с использованием существующего блокирующего SDK. Возможные результаты:Выбор правильной обработки исключений в scala
- Клиент найден
- Клиент не найден (возвращается как NotFoundException из SDK)
- Ошибка во время разговора с удаленным сервером (SDK проливает другое исключение)
Так что я хочу, чтобы мой метод, чтобы иметь тип возвращаемого Future[Option[Customer]]
и возврата для каждого случая выше:
- Успешное будущее: Некоторые из них (заказчик)
- Успешное будущее: Нет
- Failed Future
Вот что я написал с помощью TRY/поймать:
private def findCustomer(userId: Long): Future[Option[Customer]] = future {
try {
Some(gateway.find(userId))
} catch {
case _: NotFoundException => None
}
}
Это работает отлично и кажется чистой, чтобы меня, но, похоже, это не действительно «способ Scala» - мне сказали избежать использования try/catch. Поэтому я искал способ переписать его, используя вместо этого Try
.
Здесь 2 варианта, которые (я думаю) ведут себя точно так же, используя Try
.
Вариант А:
private def findCustomer(userId: Long): Future[Option[Customer]] = future {
Try(
Some(gateway.find(userId))
).recover {
case _: NotFoundException => None
}.get
}
Вариант B:
private def findCustomer(userId: Long): Future[Option[Customer]] = future {
Try(
Some(gateway.find(userId))
).recover {
case _: NotFoundException => None
}
} flatMap {
case Success(s) => Future.successful(s)
case Failure(f) => Future.failed(f)
}
Я не большой поклонник А (хотя это более кратким, чем В), так как .get
кажется немного коварный. B определенно является наиболее явным, но отображение Try
дел на соответствующие результаты Future
кажется скучным.
Как опытный программист Scala написал бы это?
Красивая! Я думаю, что 'Future {...} recover {...}' именно то, что я искал, кратким, выразительным и идиоматичным. Благодаря! –
Это хорошо, но вы должны изменить параметр Some => Option для защиты от Some (null). –
@TaylorLeese, вы правы. Я использовал 'Some', потому что знал, что метод будет генерировать, когда пользователь не существует, но не имеет смысла использовать' Option'. –