2017-02-16 5 views
1

Прямо сейчас я использую akka-stream и akka-HTTP для создания API потоковой передачи файлов. Таким образом я инъекционный источник потоковый в сущность, чтобы данные в потоковом непосредственно клиент HTTP так:Как получить сообщение об ошибке akka-stream в akka-http для входа в систему и сообщить об этом клиенту правильно?

complete(HttpEntity(ContentTypes.`application/octet-stream`, source)) 

Однако, если по каким-то причинам потока терпит неудачу, то соединение закрывается с помощью Акки-клиент без дальнейшего объяснение или ведение журнала.

мне нужно было 2 вещи:

  • Как я могу получить журналы исключений?
  • Как я могу уведомить своего клиента с сообщением перед закрытием соединения?

Спасибо

+0

Я подал вопрос об ошибке не регистрируется должным образом: https://github.com/ AKKA/Акка-HTTP/вопросы/894. К сожалению, отправка потоком какого-либо статуса клиенту невозможна при потоковой передаче. В большинстве случаев, когда возникает ошибка, akka-http находится в середине переноса объекта ответа клиенту. В протоколе HTTP нет механизма, который бы позволял сигнализировать об ошибке клиенту, кроме сброса соединения (что мы и делаем). – jrudolph

ответ

0

Как упомянуто в протоколе HTTP комментарий не позволяет сигнализировать об ошибке на стороне клиента.

Что касается регистрации: Для меня это сводится к отсутствию надлежащей директивы журнала доступа в akka http.

В моем текущем проекте у нас есть декоратор, который регистрирует обработчик onComplete для http-объекта, прежде чем передать его в akka http для рендеринга.

private def onResponseStreamEnd(response: HttpResponse)(action: StatusCode => Unit): HttpResponse = 
    if (!response.status.allowsEntity() || response.entity.isKnownEmpty()) { 
     action(response.status) 
     response 
    } else { 
     val dataBytes = 
     onStreamEnd(response.entity) { result => 
      val overallStatusCode = 
      result match { 
       case Success(_) => 
       response.status 

       case Failure(e) => 
       logger.error(e, s"error streaming response [${e.getMessage}]") 
       StatusCodes.InternalServerError 
      } 

      action(overallStatusCode) 
     } 

     response.withEntity(response.entity.contentLengthOption match { 
     case Some(length) => HttpEntity(response.entity.contentType, length, dataBytes) 
     case None   => HttpEntity(response.entity.contentType, dataBytes) 
     }) 
    } 

    private def onStreamEnd(entity: HttpEntity)(onComplete: Try[Done] ⇒ Unit): Source[ByteString, _] = 
    entity.dataBytes.alsoTo { Sink.onComplete(onComplete) } 

Использование:

complete(onResponseStreamEnd(HttpResponse(StatusCodes.OK, HttpEntity(ContentTypes.`application/octet-stream`, source))){ statusCode => .... }) 

Подобный подход, но с использованием стадии пользовательского графика вы можете найти here

Смежные вопросы