2017-04-20 58 views
1

我需要在我的http響應中將異常消息編碼爲特定的JSON格式。我想知道如何在我的路由或其外部捕獲DeserializationException或編碼DeserializationException。處理(序列化,實際上..)在akka-http中的DeserializationException

我試過如下:

1)異常在我的路由處理:

val exceptionHandler = ExceptionHandler { 
    case e: DeserializationException => complete(StatusCodes.BadRequest, ServiceBrokerError(e.getMessage)) 
} 

2)在隱含範圍JSON格式DeserializationException

implicit object DeserializationExceptionFormat extends DefaultJsonProtocol with RootJsonFormat[DeserializationException] { 

    def write(e: DeserializationException) = JsObject("message" -> JsString(e.getMessage)) 
    def read(v: JsValue) = throw new NotImplementedError() 

} 

這些都不作任何區別和DeserializationException s仍然編碼到下面的http響應正文中:

HTTP/1.1 400 Bad Request 
Content-Length: 74 
Content-Type: text/plain; charset=UTF-8 
Date: Thu, 20 Apr 2017 21:23:11 GMT 
Server: akka-http/10.0.1 

The request content was malformed: 
Node count may not be a floating number 

任何建議,非常感謝。

一些額外的上下文我的路線依靠噴霧JSON整合到地圖請求實體對象,如:

// service instance management related routes 
put { 
    entity(as[CreateInstance]) { createInstance => handleCreateInstance(s"cluster-$clusterId", createInstance) } 
} 

回答

0

我應該只看了MarshallingDirectives.entity,因爲它吞下序列化相關的異常並將它們轉換爲拒絕:

/** 
    * Unmarshalls the requests entity to the given type passes it to its inner Route. 
    * If there is a problem with unmarshalling the request is rejected with the [[Rejection]] 
    * produced by the unmarshaller. 
    * 
    * @group marshalling 
    */ 
    def entity[T](um: FromRequestUnmarshaller[T]): Directive1[T] = 
    extractRequestContext.flatMap[Tuple1[T]] { ctx ⇒ 
     import ctx.executionContext 
     import ctx.materializer 
     onComplete(um(ctx.request)) flatMap { 
     case Success(value) ⇒ provide(value) 
     case Failure(RejectionError(r)) ⇒ reject(r) 
     case Failure(Unmarshaller.NoContentException) ⇒ reject(RequestEntityExpectedRejection) 
     case Failure(Unmarshaller.UnsupportedContentTypeException(x)) ⇒ reject(UnsupportedRequestContentTypeRejection(x)) 
     case Failure(x: IllegalArgumentException) ⇒ reject(ValidationRejection(x.getMessage.nullAsEmpty, Some(x))) 
     case Failure(x) ⇒ reject(MalformedRequestContentRejection(x.getMessage.nullAsEmpty, x)) 
     } 
    } & cancelRejections(RequestEntityExpectedRejection.getClass, classOf[UnsupportedRequestContentTypeRejection]) 

因此,它是一個拒絕,我必須處理,而不是DeserializationException。

1

如果你改變你的異常處理程序

val exceptionHandler = ExceptionHandler { case e: DeserializationException => complete(StatusCodes.BadRequest, e) }

+0

感謝您的回答。這是相同的輸出。我不認爲這個問題是ServiceBrokerError對象的編碼,或者至少我希望會有記錄的東西。 – pgn

相關問題