2

このガイドの例を使用して、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 + スプレー テストキットでテストすると、正しいエラー メッセージが返されることはなく、代わりにデフォルトの 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 が実行されないことがわかりました。

なぜうまくいかないのか、解決策を知っている人はいますか?

4

1 に答える 1

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すべてのテストが継承する基本クラスに入れただけです。

于 2018-02-15T17:46:24.680 に答える