2016-07-06 2 views
2

Я пытаюсь ExceptionHandler Spray, используя пример в данном руководстве: http://spray.io/documentation/1.2.2/spray-routing/key-concepts/exception-handling/ExceptionHandler не работает с распылителем-комплектом?

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" 
     } 
     } 
    } 
} 

Если я сделал запрос с завитком, она возвращает сообщение об ошибке Bad numbers, bad result!!! правильно. Однако при тестировании с помощью тест-теста Specs2 + он никогда не возвращает правильное сообщение об ошибке, вместо этого он возвращает сообщение об ошибке с кодом 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 никогда не получить выполняется.

Кто-нибудь знает, почему это не работает, и решение?

+0

Отличный вопрос! Благодарим за то, что он разбил его на усвояемый пример. Я дважды сталкивался с подобными проблемами. Этот ответ, наконец, помог мне :) – stholzm

ответ

0

Видимо 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 в базовый класс, на который наследуются все тесты.

Смежные вопросы