Handling downstream IOExceptions in Akka HTTP server

Viewed 71

How do I catch downstream exceptions such as java.io.IOException when returning responses? I tried using CancellationStrategy.FailStage attribute but stage still completes successfully when using watchTermination?

// my.app.WebServer

Http()
      .newServerAt(config.server.host, config.server.port)
      .connectionSource()
      .log("connection", _.remoteAddress.toString)
      .addAttributes(Attributes.logLevels(onElement = Attributes.LogLevels.Debug,
                                          onFinish = Attributes.LogLevels.Debug,
                                          onFailure = Attributes.LogLevels.Error))
      .addAttributes(Attributes(CancellationStrategy(CancellationStrategy.FailStage)))
      .recover {
        case ex =>
          log.error("Connection error", ex)
          throw ex
      }
      .runForeach(_.handleWithAsyncHandler(route))

// my.app.Api

  private def respondWith(httpResponse: HttpResponse): Route = {
    complete {
      httpResponse
        .withEntity(HttpEntity(
          httpResponse.entity.contentType,
          httpResponse.entity.dataBytes
            .log("response")
            .addAttributes(Attributes.logLevels(onElement = Attributes.LogLevels.Off,
                                                onFinish = Attributes.LogLevels.Info,
                                                onFailure = Attributes.LogLevels.Error))
            .addAttributes(Attributes(CancellationStrategy(CancellationStrategy.FailStage)))
            .watchTermination()((_, future) =>
              future.onComplete {
                case Success(_)  => log.info("Response completed")
                case Failure(ex) => log.error("Response failed", ex)
            })
        ))
    }
  }

// Log

2021-12-13T08:11:55,346 DEBUG [63] akka.io.TcpListener: New connection accepted
2021-12-13T08:11:55,348 DEBUG [56] akka.stream.Materializer: [connection] Element: /0:0:0:0:0:0:0:1:51294
2021-12-13T08:11:55,353 DEBUG [56] ...
2021-12-13T08:11:57,675 DEBUG [52] akka.io.TcpIncomingConnection: Closing connection due to IO error java.io.IOException: Broken pipe
2021-12-13T08:11:57,911 INFO  [17] my.app.Api$: Response completed
2021-12-13T08:11:57,912 INFO  [17] akka.stream.Materializer: [response] Downstream finished, cause: SubscriptionWithCancelException$NoMoreElementsNeeded$: null
0 Answers
Related