Обрабатывать будущее с помощью трансформации - PullRequest
1 голос
/ 29 марта 2020

У меня бот-телеграмма на Scala, и я хочу отправить изображение пользователю, если оно существует, и сообщение «Извините, изображение не существует», если это не так. И у меня есть функция getImage(tag), которая возвращает Future.successful(link) или Future.failed(NoImageException(msg)).

onCommand("/img") { implicit msg =>
  val tag = msg.text.get.drop("/img ".length)
  try {
    if (tag.isEmpty) throw new IndexOutOfBoundsException()
    service.getImage(tag).transform {
      case Success(link) => Success(
        try {
          replyWithPhoto(InputFile(link))
        } catch {
          case _ => reply(link) // maybe it isn't a photo...
        })
      case Failure(e) => Success(reply(e.getMessage))
    }.void
  } catch {
    case _: IndexOutOfBoundsException => reply("Empty argument list. Usage: /img tag").void
  }}

И этот код отправляет изображение в случае успеха, но не отправляет сообщение, если это сбой (но он определенно выбирает case Failure(e) в этом случае)

1 Ответ

0 голосов
/ 29 марта 2020

reply семейство функций возвращает Future[Message]. В настоящее время вы переносите результат reply в Success, поэтому результат вашего transform равен Future[Future[Message]], что не работает. Вместо этого вы можете использовать transformWith, который ожидает Future результата от своего аргумента:

onCommand("/img") { implicit msg =>
  val tag = msg.text.get.drop("/img ".length)
  val message: Future[Message] =
    if (tag.isEmpty) reply("Empty argument list. Usage: /img tag")
    else {
      service.getImage(tag).transformWith {
        case Success(link) => replyWithPhoto(InputFile(link)).recoverWith {
          case _ => reply(link) // maybe it isn't a photo...
        }
        case Failure(e) => reply(e.getMessage)
      }
    }
  message.void
}

Обратите внимание, что я также удалил оба оператора try. Внешнее просто не нужно, потому что вы можете просто использовать if / else. Внутренний не будет работать вообще, потому что replyWithPhoto возвращает Future. Таким образом, он не выдает ошибок, и вам нужно recover или transform, когда это не удается.

...