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

时间:2015-12-22 10:17:50

标签: json scala playframework jackson

我有一个Play框架应用程序,它将JSON发布到它。

将一个特定呼叫的所有无效数据记录为内部监控的错误非常重要。

我设法找到了一个通过我的尝试/捕获的方案。

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

{
   "key": "broken "value""
}

你会在动作方法之外抛出异常

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]

您可以看到从此处注销为调试消息

https://github.com/playframework/playframework/blob/92078f9cc751a5c19117dede18c7ca63aca73347/framework/src/play/src/main/scala/play/api/mvc/ContentTypes.scala#L869

但我不知道自己如何能够抓住这个,将其记录为错误(并注销无效的请求正文

https://groups.google.com/forum/#!topic/play-framework/bh7MU9_AFsQ看起来似乎不太可能 - 想知道是否有人有任何进一步的想法?

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

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

0 个答案:

没有答案