Как справиться с ошибкой ответа HTTP-клиента Akka

Запросы HTTP-клиента Akka возвращают Future[HttpResponse] — как справиться с ошибкой Future? Просто запротоколировать ошибку или повторно передать ее супервайзеру?

Есть ли документация о типе ошибок, которые могут быть возвращены клиентом (и, следовательно, автоматически переданы супервизору), а также об ошибках, которые могут привести к сбою Furure.


person EugeneMi    schedule 06.11.2016    source источник


Ответы (1)


Это дело вкуса в основном. Обычно я преобразовываю Future[HttpResponse] в Future[Try[HttpResponse]], а затем обрабатываю его как

response.flatMap { tryResp =>

  tryResp match {
    case Success(res) =>
      res.status match {
        case OK =>
          // Unmarshal response here into Future[Something]
        case Found =>
          // Handle  redirect by calling requestBlhBlah() again with anotehr URI
        case _ =>
          // I got status code I didn't expect so I wrap it along with body into Future failure
          Unmarshal(res.entity).to[String].flatMap { body =>
            Future.failed(new IOException(s"The response status is ${res.status} [${request.uri}] and response body is $body"))
          }
      }
    case Failure(ex) =>
      Future.failed(ex)
  }
}

Если вы используете поточный клиент, вы также можете указать Decider для обработки ошибок.

val decider: Decider = {
  case ex =>
    ex.printStackTrace()
    Supervision.Stop // Passes error down to subscriber
}

а затем использовать его в любом материализаторе

implicit val materializer = ActorMaterializer(ActorMaterializerSettings(system).withSupervisionStrategy(decider))(system)

или в зависимости от потока через .withAttributes(ActorAttributes.supervisionStrategy(decider))

Что касается Future сбоя, вам решать, как с этим справиться. Вы можете преобразовать отказ во что-то другое, используя recoverWith, или зарегистрировать его в Future.onFailure.

person expert    schedule 06.11.2016
comment
Ахм... Я вроде как делаю то же самое, но с "Или" вместо "Попробовать" - конечным результатом является то, что если все в порядке, возвращается Future[Something], в противном случае возвращается неудачное будущее либо с исключением в исходном ответе ( Future[HttpResponse]), или какое-либо исключение клиента, которое мы определяем для ответа на известную ошибку от целевой службы. - person EugeneMi; 06.11.2016
comment
Однако (1) исключение, возвращаемое future, никогда не передается супервизору и, следовательно, никогда не обрабатывается, (2) мы должны знать, какие исключения клиент может вернуть, и либо обрабатывать, либо регистрировать их. - person EugeneMi; 06.11.2016
comment
Спасибо за обновление. Все еще трудно решить, как обрабатывать ошибки, если мы не знаем, какими они могут быть. Ошибки, выдаваемые клиентом, обрабатываются супервизором, но, не зная, какая ошибка может быть возвращена в будущем, невозможно узнать, как и должны ли мы их обрабатывать. - person EugeneMi; 06.11.2016
comment
Ну, я просто покрываю случаи, о которых знаю, а другие идут в журнал :) - person expert; 06.11.2016