【问题标题】:ExceptionHandler doesn't work with spray test-kit?ExceptionHandler 不适用于喷雾测试套件?
【发布时间】:2016-07-06 20:01:31
【问题描述】:

我正在使用本指南中的示例尝试 Spray 的 ExceptionHandler:http://spray.io/documentation/1.2.2/spray-routing/key-concepts/exception-handling/

class MyServiceActor extends Actor with MyService  {

  def actorRefFactory = context

  def receive = runRoute(handleExceptions(myExceptionHandler)(myRoute))

  implicit def myExceptionHandler(implicit log: LoggingContext) =
    ExceptionHandler {
      case e: ArithmeticException =>
        requestUri { uri =>
          complete(InternalServerError, "Bad numbers, bad result!!!")
        }
    }
}

我故意将ArithmeticException 扔在这样的路线中:

trait MyService extends HttpService {

  val myRoute =
    path("") {
      get {
        complete {
          throw new ArithmeticException("Oops, I failed!")
          "Hello World"
        }
      }
    }
}

如果我使用 curl 发出请求,它会正确返回错误消息 Bad numbers, bad result!!!。但是,当使用 Specs2 + spray testkit 进行测试时,它永远不会返回正确的错误消息,而是返回默认的 500 代码错误消息 There was an internal server error。即使使用sealRoute 也无济于事。

"Test" in {
  Get() ~> sealRoute(myRoute) ~> check {
    println(responseAs[String]) // Always print `There was an internal server error.`
    ok
  }
}

在控制台上,我会看到错误跟踪:

[ERROR] [07/07/2016 00:31:24.661] [specs2.DefaultExecutionStrategy-1] [ActorSystem(com-example-MyServiceSpec)] Error during processing of request HttpRequest(GET,http://example.com/,List(),Empty,HTTP/1.1)
java.lang.ArithmeticException: Oops, I failed!
        at com.example.MyService$$anonfun$1.apply(MyService.scala:62)
        at com.example.MyService$$anonfun$1.apply(MyService.scala:61)
        at spray.routing.directives.RouteDirectives$$anonfun$complete$1$$anon$3.apply(RouteDirectives.scala:49)
        at spray.routing.directives.RouteDirectives$$anonfun$complete$1$$anon$3.apply(RouteDirectives.scala:48)
        at spray.routing.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:30)
        ...

我在myExceptionHandler 中放了一个 println 命令,发现 myExceptionHandler 永远不会被执行。

有人知道为什么它不起作用以及解决方案吗?

【问题讨论】:

  • 好问题!感谢您将其分解为一个易于理解的示例。我两次遇到类似的问题。这个答案终于帮助了我:)

标签: scala spray spray-test


【解决方案1】:

显然sealRoute 是不够的,因为异常处理程序是隐式解析的,如下所述:http://spray.io/documentation/1.2.4/spray-testkit/

在你的情况下,MyServiceActor 有一个异常处理程序,但是在测试用例中你直接使用了MyService/myRoute,所以异常处理程序没有被拾取。

这个文档页面很有用:http://spray.io/documentation/1.2.4/spray-routing/key-concepts/exception-handling/

解决方案是将隐式ExceptionHandler 引入在测试用例中的范围。所以在这个例子中:

"Test" in {
  implicit val testExceptionHandler = ExceptionHandler {
    case e: ArithmeticException =>
      requestUri { uri =>
        complete(InternalServerError, "Bad numbers, bad result!!!")
      }
  }
  Get() ~> sealRoute(myRoute) ~> check {
    println(responseAs[String])
    ok
  }
}

它起作用了,但是复制当然不是很优雅。也许您可以在测试中从MyServiceActor 访问异常处理程序并重用生产代码。我只是将testExceptionHandler 放入所有测试都继承自的基类中。

【讨论】:

    猜你喜欢
    • 2015-03-03
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    相关资源
    最近更新 更多