[英]How to get error from akka-stream propagate to akka-http to both be logged and notify the client properly?
Right now I am using akka-stream
and akka-HTTP
to build a file streaming API. 现在我使用
akka-stream
和akka-HTTP
来构建文件流API。 As such I am injecting a streaming source into an entity to have data streamed directly to the HTTP client like so: 因此,我将流式源注入实体,以便将数据直接流式传输到HTTP客户端,如下所示:
complete(HttpEntity(ContentTypes.`application/octet-stream`, source))
However, if for some reason the stream fails, the connection gets closed by akka-http without further explanation or logging. 但是,如果由于某种原因流失败,则连接将被akka-http关闭,而无需进一步说明或记录。
I would need 2 things: 我需要两件事:
Thank you 谢谢
As mentioned in comment HTTP protocol does not allow to signal error to the client side. 正如评论中所提到的,HTTP协议不允许向客户端发出错误信号。
As to logging: For me it boils down to missing proper access log directive in akka http. 关于日志记录:对我来说,它归结为缺少akka http中的正确访问日志指令。
In my current project we have decorator which register onComplete handler for http entity before giving it to akka http for rendering. 在我当前的项目中,我们有装饰器,它为http实体注册onComplete处理程序,然后将其提供给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) }
Usage: 用法:
complete(onResponseStreamEnd(HttpResponse(StatusCodes.OK, HttpEntity(ContentTypes.`application/octet-stream`, source))){ statusCode => .... })
Similar approach but using custom graph stage you can find here 类似的方法,但使用自定义图阶段,你可以在这里找到
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.