【问题标题】:Why is Akka HTTP Routing Catching My Exception?为什么 Akka HTTP 路由捕获了我的异常?
【发布时间】:2019-01-23 00:39:25
【问题描述】:

鉴于此代码

def leaderboardPost(name: Option[String]): Route =
  post {
    logRequest("leaderboard", Logging.DebugLevel) {
      handleRejections(postBodyRejections) {
        entity(as[LeaderboardPostRequest]) { leaderboard =>
          try {
            complete(leaderboardCreate(Some(leaderboard.name), Some(leaderboard.kind)))
          } catch {
            case cause: DuplicateIDException =>
              logger.error(cause)
              complete(cause.response)
            case cause: UnknownKindException =>
              logger.warn(cause)
              complete(cause.response)
            case cause: Throwable =>
              logger.error(cause)
              complete(HttpResponse(InternalServerError, entity = s"Exception thrown from LeaderboardPost: ${cause.getMessage}"))
          }
        }
      }
    }
  }

leaderboardCreate 抛出UnknownKindException 时,路由代码会捕获它并将其转换为Completing with 500 Internal Server Error response. To change default exception handling behavior, provide a custom ExceptionHandler.

虽然我正在考虑创建一个自定义 ExceptionHandler,但我不明白我为什么需要这样做。我的代码应该捕获它并返回complete(cause.response)。 Akka HTTP 如何在我的代码之前捕获异常?

【问题讨论】:

    标签: scala akka akka-http


    【解决方案1】:

    根据我的理解,这是因为 leaderboardCreate 实际上并没有像您预期的那样与 complete 调用同步执行。 complete 方法返回一个从 Route 扩展而来的 StandardRoute,定义为:

    type Route = RequestContext ⇒ Future[RouteResult]
    

    换句话说,“路由”是从上下文到FutureRouteResult)的函数。如果你看一下complete 的定义,它就是:

    def complete(m: ⇒ ToResponseMarshallable): StandardRoute =
      StandardRoute(_.complete(m))
    

    注意 之前的ToResponseMarshallable。这是传递一个参数by name,它有效地将它变成了一个惰性求值。

    换句话说,您所有的try/catch 包装都是非常小的(且无异常)代码,用于构建StandardRoute,它将您的逻辑捕获为惰性值,而不是逻辑本身的执行。这就是为什么你需要一个custom ExceptionHandler,当它运行时,你(或者更确切地说是Akka)可以将它放入Future 的错误处理程序链中。

    【讨论】:

    • 很好的解释。谢谢。使用自定义的 ExceptionHander 解决了这个问题。
    • @EricKolotyluk,好吧,如果这是您问题的答案,为什么不将其标记为已接受?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-07
    • 2010-11-16
    • 2012-01-22
    • 2016-06-08
    相关资源
    最近更新 更多