Scalatra:打印所有API的

时间:2016-03-03 18:37:51

标签: scala scalatra

我有一个带有多个REST API的scalatra servlet。出于日志记录的目的,我使用after()方法在调用每个API后打印出返回状态代码。

after() {
  logger.info("request {} {} returned with status code {}", request.getMethod, request.getRequestURL, response.getStatus.toString)
}

我注意到当方法返回halt时,状态代码会正确打印,但是当方法返回最后一行的状态代码(没有halt)时,状态代码是无论实际状态如何,将被打印的总是200。

例如:

post("/users/:user") {

  try {

    //some logic here...
    if(condition)
     halt(InternalServerError("DB error"))  //this will cause status 500 to be printed in the 'after' method


  } catch {
    case e: Exception =>
      InternalServerError("an unknown error occurred") //this will cause status 200 to be printed in the 'after' method
  }
}

用户在两种情况下都会获得真实的状态代码(500)。

知道为什么会这样吗?这是一个错误吗? 我在scalatra-user邮件列表上发布了这个问题,但列表似乎非常不活跃。

阿里扎

1 个答案:

答案 0 :(得分:1)

(免责声明:我不是Scalatra开发人员,但我一直在将它用于项目。这是基于我不久前阅读代码。)

这与Scalatra处理抛出异常的方式有关(相关代码似乎从this one开始)。如果抛出runActions异常的某个地方(halt抛出HaltException),catch cradleHalt块将会被调用,我们会转到{{ 1}}将设置响应状态代码。

如果您未调用renderHaltException但直接返回halt,则情况并不完全相同。在这种情况下,ActionResult似乎会产生一个值,然后传递给executeRoutes,然后调用renderResponse,最后调用renderResponseBodyThis block似乎是实际设置renderPipeline的实际状态代码的地方。但是,ActionResult函数已被调用(它在after中调用,在actionResult返回之前)。所以你得到的正是你的行为:当你不使用executeRoutes时,正确的响应状态只在实际响应中设置,而不是在你的记录调用中设置。

您可能已经尝试过此操作,但是halt在记录时未生成正确的HTTP状态代码的快速修复只是将其包含在另一个InternalServerError调用中。

至于这是否是一个bug,我不能说。我猜可能不是,因为他们确实在halt文档中说executeRoutesafter传递给actionResult之前被调用。不清楚的是,呈现renderResponse的行为还设置了您想要记录的HTTP错误代码。

你必须与他们确认:)。