在Play框架的应用程序代码中捕获JsonParseException

在Play框架的应用程序代码中捕获JsonParseException,json,scala,playframework,jackson,Json,Scala,Playframework,Jackson,我有一个Play框架应用程序,它可以发布JSON 非常重要的是,我们要将一个特定调用中的所有无效数据记录为错误,以便进行内部监控 我已经设法找到了一个场景,让我的尝试/捕获失败 如果您有无效的JSON,其中一些双引号没有被转义 { "key": "broken "value"" } 您会在action方法外部引发异常 com.fasterxml.jackson.core.JsonParseException: Unexpected character ('M' (code 77)): w

我有一个Play框架应用程序,它可以发布JSON

非常重要的是,我们要将一个特定调用中的所有无效数据记录为错误,以便进行内部监控

我已经设法找到了一个场景,让我的尝试/捕获失败

如果您有无效的JSON,其中一些双引号没有被转义

{
   "key": "broken "value""
}
您会在action方法外部引发异常

com.fasterxml.jackson.core.JsonParseException: Unexpected character ('M' (code 77)): was expecting comma to separate OBJECT entries
at [Source: [B@75618a1f; line: 32, column: 43]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1419) ~[jackson-core-2.4.1.jar:2.4.1]
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:508) ~[jackson-core-2.4.1.jar:2.4.1]
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:437) ~[jackson-core-2.4.1.jar:2.4.1]
at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:680) ~[jackson-core-2.4.1.jar:2.4.1]
at play.api.libs.json.JsValueDeserializer.deserialize(JsValue.scala:408) ~[play-json_2.11-2.3.8.jar:2.3.8]
at play.api.libs.json.JsValueDeserializer.deserialize(JsValue.scala:360) ~[play-json_2.11-2.3.8.jar:2.3.8]
at play.api.libs.json.JsValueDeserializer.deserialize(JsValue.scala:355) ~[play-json_2.11-2.3.8.jar:2.3.8]
at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:3023) ~[jackson-databind-2.4.1.1.jar:2.4.1.1]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1637) ~[jackson-databind-2.4.1.1.jar:2.4.1.1]
at play.api.libs.json.JacksonJson$.parseJsValue(JsValue.scala:482) ~[play-json_2.11-2.3.8.jar:2.3.8]
at play.api.libs.json.Json$.parse(Json.scala:30) ~[play-json_2.11-2.3.8.jar:2.3.8]
at play.api.mvc.BodyParsers$parse$$anonfun$tolerantJson$1.apply(ContentTypes.scala:365) ~[play_2.11-2.3.8.jar:2.3.8]
at play.api.mvc.BodyParsers$parse$$anonfun$tolerantJson$1.apply(ContentTypes.scala:361) ~[play_2.11-2.3.8.jar:2.3.8]
at play.api.mvc.BodyParsers$parse$$anonfun$tolerantBodyParser$1$$anonfun$27$$anonfun$apply$79.apply(ContentTypes.scala:866) ~[play_2.11-2.3.8.jar:2.3.8]
at scala.util.control.Exception$Catch$$anonfun$either$1.apply(Exception.scala:125) ~[scala-library-2.11.6.jar:na]
at scala.util.control.Exception$Catch$$anonfun$either$1.apply(Exception.scala:125) ~[scala-library-2.11.6.jar:na]
at scala.util.control.Exception$Catch.apply(Exception.scala:103) ~[scala-library-2.11.6.jar:na]
at scala.util.control.Exception$Catch.either(Exception.scala:125) ~[scala-library-2.11.6.jar:na]
at play.api.mvc.BodyParsers$parse$$anonfun$tolerantBodyParser$1$$anonfun$27.apply(ContentTypes.scala:865) [play_2.11-2.3.8.jar:2.3.8]
at play.api.mvc.BodyParsers$parse$$anonfun$tolerantBodyParser$1$$anonfun$27.apply(ContentTypes.scala:864) [play_2.11-2.3.8.jar:2.3.8]
at play.api.libs.iteratee.Iteratee$$anonfun$map$1.apply(Iteratee.scala:471) [play-iteratees_2.11-2.3.8.jar:2.3.8]
at play.api.libs.iteratee.Iteratee$$anonfun$map$1.apply(Iteratee.scala:471) [play-iteratees_2.11-2.3.8.jar:2.3.8]
at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$14.apply(Iteratee.scala:496) [play-iteratees_2.11-2.3.8.jar:2.3.8]
at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$14.apply(Iteratee.scala:496) [play-iteratees_2.11-2.3.8.jar:2.3.8]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) [scala-library-2.11.6.jar:na]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) [scala-library-2.11.6.jar:na]
at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:46) [play-iteratees_2.11-2.3.8.jar:2.3.8]
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:40) [scala-library-2.11.6.jar:na]
at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:248) [scala-library-2.11.6.jar:na]
at scala.concurrent.Promise$class.complete(Promise.scala:55) [scala-library-2.11.6.jar:na]
at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:153) [scala-library-2.11.6.jar:na]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:23) [scala-library-2.11.6.jar:na]
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:41) [akka-actor_2.11-2.3.4.jar:na]
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393) [akka-actor_2.11-2.3.4.jar:na]
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library-2.11.6.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library-2.11.6.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library-2.11.6.jar:na]
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library-2.11.6.jar:na]
此时,您可以将其作为调试消息注销

但我不知道如何自己捕捉到这一点,将其作为错误注销(并注销无效的请求正文)

从表面上看,这似乎是不可能的-想知道是否有人有任何进一步的想法

作为参考,我的行动方法如下

def createTransaction =
withUser { auth => request =>
  request.body.asJson.map { json =>
    unmarshallTransactionResource(json, (resource: Transaction) => {
      try {
        if (auth.device.isDefined) {
          val id = transactionService.createTransactionForDevice(resource, auth.device.get)
          if (id.isDefined) {
            val transResp = TransactionResponse(id.get)
            Created(Json.toJson(transResp))
          } else {
            Logger.error("Failed transaction insert: " + json.toString())
            Conflict
          }
        } else {
          Forbidden
        }
      } catch {
        case unknown: Throwable  => Logger.error("Exception thrown handling transaction: " + unknown.getMessage + " JSON: "+ json.toString())
          BadRequest
      }
    })
  }.getOrElse{
    Logger.error("Failed transaction json decode: " + request.body.asText)
    BadRequest
  }
}

此异常是由正文解析器尝试读取json值引起的。您可能希望使用自定义正文解析器来记录解析失败,或者您可以覆盖播放(参见)并在此处记录异常。此异常是由正文解析器尝试读取json值引起的。您可能希望使用自定义正文解析器记录失败的解析,或者可以覆盖播放(cf.)并在此处记录异常。