ExceptionHandler не работает с аэрозольным тест-китом?
Я пытаюсь использовать 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)
...
Я положил команду println в myExceptionHandler
и обнаружил, что myExceptionHandler никогда не будет выполнен.
Кто-нибудь знает, почему не работает и решение?
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
в базовый класс, все тесты наследуются от.