возвращаемый тип для findAndModify с фьючерсами

#scala #future #reactive-programming

#скала #будущее #реактивное программирование

Вопрос:

Допустим, я использую асинхронную библиотеку для чтения и записи данных. В случае сбоя я получаю сообщение об ошибке в виде строки, в противном случае — данные. Есть ли лучший способ представить возвращаемый тип, чем Future[Either[String, Future[Data]]] ?

Возможная реализация:

   def createData(name: String): Future[Either[String, Future[Data]]] = {
    dataDAO.findOneByName(name).flatMap {
      case Some(data) =>
        Future.successful(Left(s"Data with name already exists. $name"))
      case None =>
        val data = Data.createFromName(name)
        dataDAO.save(data).map {
          lastError =>
            data
        }.right.futureSuccessful
      }
    }
 

Комментарии:

1. Зачем использовать Future[Either[String, Future[Data]]] вместо Future[Either[String, Data]] ?

2. Почему бы не обернуть сообщение об ошибке в исключение и использовать Future.failed ?

3. @izstas я думаю, что использование исключения здесь было бы плохим. Вы не должны использовать исключения для «бизнес-ошибок», а уже существующая запись — это полностью ожидаемый сценарий, поэтому это не «исключение». Использование either в качестве возвращаемого типа делает подпись намного более понятной и подробной для потребителя.

Ответ №1:

Ваш возвращаемый тип должен быть Future[Either[String, Data]]

Чтобы заархивировать это, вам нужно изменить свой второй случай на:

 case None =>
    val data = Data.createFromName(name)
    dataDAO.save(data).map {
      _ => Right(data)
    }
 

Я бы даже улучшил ваш тип ошибки с String на , например CreateDataError , так, чтобы ваш возвращаемый тип был Future[Either[CreateDataError, Data]] бы, и ваш первый случай был бы

 // Having somewhere decalred
trait CreateDataError
object DataAlreadyExistsError

//...
//...

case Some(data) =>
    Future.successful(Left(DataAlreadyExistsError))
 

Комментарии:

1. Спасибо! Очевидно, я упустил из виду это будущее / любую комбинацию.