0

I am sending this json to my scala code but I am getting error `` when the json is getting parsed.

{"practice-question":{"title":"dummy title","description":"<p>some D</p><p><strong>with bold</strong></p><ol><li><strong>no 1</strong></li></ol>","tags":["javascript"],"references":["dummy references"],"hints":["<p><u>some hint</u></p>"],"image":["data:image/png;base64,iVBORw0],"answer":[{"filename":"c.js","answer":"function c(){\n    c;\n}"}],"success-test":"dummy success test","fail-test":"dummy fail test"}}))

The json validation starts at

 val questionOption = jsonBody.validateOpt[Question] //should give JsSuccess or JsError

It should call the following Reads

 implicit val questionReads:Reads[Question] = (JsPath \ "practice-question").read[PracticeQuestion](PracticeQuestionReads)
        .map((x:PracticeQuestion)=>Question.apply (x))

The Reads for PracticeQuestion is

implicit object PracticeQuestionReads extends Reads[PracticeQuestion] {
    def reads(json:JsValue):JsResult[PracticeQuestion]  =  {
      println(s"validating json ${json}")
      val structurallyValidated = json.validateOpt[PracticeQuestion](practiceQuestionValidateStructureReads) //check that structurally the json maps to PracticeQuestion
      println(s"structurally validated ${structurallyValidated}")
      val structuralValidationResult = structurallyValidated match {
        case JsSuccess(questionOpt,path)=>{
          val result = questionOpt.map(question=>{
              //TODOM - should check size of other lists (hints, references etc.)
            if(question.image.length <0 || question.image.length > 3)
            {
              JsError("invalid no. of images")
            }
            else {
              JsSuccess(question)
            }
          }).getOrElse(JsError("Error in validating Json"))
          result
        }
        case JsError(errors) =>{
          //TODOM - replace print with logger.
          println("errors in json structure: "+errors)
          JsError(errors)
        }
      }

      structuralValidationResult match {
        case JsSuccess(question,path)=>{
          //TODOM - check that for other mandatory fields (esp in Lists)are not empty
          if(question.answer.length == 0){
            JsError("Missing Answer")
          } else {
            JsSuccess(question);
          }
        }
        case JsError(errors) =>{
          JsError(errors)
        }
      }
    }
  }

and Reads used in PracticeQuestionReads is

  implicit val practiceQuestionValidateStructureReads: Reads[PracticeQuestion] = {
    println("in conversion");
    val p =  //p is of type FunctionBuilder[Reads]#CanBuild. This is an intermediary object used to create Reads[PracticeQuestion].
    (JsPath \ "question-id").readNullable[UUID] and
      (JsPath \ "description").read[String] and
      (JsPath \ "hints").read[List[String]] and
      (JsPath \ "image").read[List[String]] and //while image data is optional, this field is always present i.e. will get at least image:[]
      (JsPath \ "success-test").read[String] and
      (JsPath \ "fail-test").read[String] and
      (JsPath \ "tags").read[Set[String]] and
      (JsPath \ "title").read[String] and
      (JsPath \ "answer").read[List[AnswerSection]] and
      (JsPath \ "references").read[List[String]] and
      (JsPath \ "question-creator").readNullable[QuestionCreator] and
      (JsPath \ "creation-year").readNullable[Long] and //year/month are for internal consumption so not worried about receiving it from a client
      (JsPath \ "creation-month").readNullable[Long] and
      (JsPath \ "creation-hour").readNullable[Long] and
      (JsPath \ "creation-minute").readNullable[Long]
    //apply method of CanBuildX with a function to translate individual values to your model, this will return your complex Reads
   val q = p.apply((PracticeQuestion.apply _))

    q

  }

To me the structure etc. look ok. What am I doing wrong?

UPDATE, after two months, the error occurred but for a different. I am running a test and am sending a json from the test. The error is

Uninitialized field: C:\Users\manuc\Documents\manu\codingjedi\code_related\code\frontend\web\app\controllers\AnswerController.scala: 34
scala.UninitializedFieldError: Uninitialized field: C:\Users\manuc\Documents\manu\codingjedi\code_related\code\frontend\web\app\controllers\AnswerController.scala: 34
    at controllers.AnswerController.logger(AnswerController.scala:34)
    at controllers.AnswerController.$anonfun$maxAllowedBodySize$1(AnswerController.scala:33)
    at scala.runtime.java8.JFunction0$mcJ$sp.apply(JFunction0$mcJ$sp.java:12)
    at scala.Option.getOrElse(Option.scala:121)
    at controllers.AnswerController.<init>(AnswerController.scala:33)
    at UnitSpecs.ControllerSpecs.AnswerControllerSpecTestEnv.<init>(AnswerControllerSpecTestEnv.scala:98)
    at UnitSpecs.ControllerSpecs.AnswerControllerUnitSpec.$anonfun$new$2(AnswerControllerUnitSpec.scala:67)
    at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
    at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
    at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
    at org.scalatest.Transformer.apply(Transformer.scala:22)
    at org.scalatest.Transformer.apply(Transformer.scala:20)
    at org.scalatest.WordSpecLike$$anon$1.apply(WordSpecLike.scala:1078)
    at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
    at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
    at org.scalatest.WordSpec.withFixture(WordSpec.scala:1881)
    at org.scalatest.WordSpecLike.invokeWithFixture$1(WordSpecLike.scala:1076)
    at org.scalatest.WordSpecLike.$anonfun$runTest$1(WordSpecLike.scala:1088)
    at org.scalatest.SuperEngine.runTestImpl(Engine.scala:289)
    at org.scalatest.WordSpecLike.runTest(WordSpecLike.scala:1088)
    at org.scalatest.WordSpecLike.runTest$(WordSpecLike.scala:1070)
    at UnitSpecs.ControllerSpecs.AnswerControllerUnitSpec.org$scalatest$BeforeAndAfterEach$$super$runTest(AnswerControllerUnitSpec.scala:32)
    at org.scalatest.BeforeAndAfterEach.runTest(BeforeAndAfterEach.scala:221)
    at org.scalatest.BeforeAndAfterEach.runTest$(BeforeAndAfterEach.scala:214)
    at UnitSpecs.ControllerSpecs.AnswerControllerUnitSpec.runTest(AnswerControllerUnitSpec.scala:32)
    at org.scalatest.WordSpecLike.$anonfun$runTests$1(WordSpecLike.scala:1147)
    at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:396)
    at scala.collection.immutable.List.foreach(List.scala:389)
    at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:384)
    at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:373)
    at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:410)
    at scala.collection.immutable.List.foreach(List.scala:389)
    at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:384)
    at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:379)
    at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:461)
    at org.scalatest.WordSpecLike.runTests(WordSpecLike.scala:1147)
    at org.scalatest.WordSpecLike.runTests$(WordSpecLike.scala:1146)
    at org.scalatest.WordSpec.runTests(WordSpec.scala:1881)
    at org.scalatest.Suite.run(Suite.scala:1147)
    at org.scalatest.Suite.run$(Suite.scala:1129)
    at org.scalatest.WordSpec.org$scalatest$WordSpecLike$$super$run(WordSpec.scala:1881)
    at org.scalatest.WordSpecLike.$anonfun$run$1(WordSpecLike.scala:1192)
    at org.scalatest.SuperEngine.runImpl(Engine.scala:521)
    at org.scalatest.WordSpecLike.run(WordSpecLike.scala:1192)
    at org.scalatest.WordSpecLike.run$(WordSpecLike.scala:1190)
    at UnitSpecs.ControllerSpecs.AnswerControllerUnitSpec.org$scalatest$BeforeAndAfterAll$$super$run(AnswerControllerUnitSpec.scala:32)
    at org.scalatest.BeforeAndAfterAll.liftedTree1$1(BeforeAndAfterAll.scala:213)
    at org.scalatest.BeforeAndAfterAll.run(BeforeAndAfterAll.scala:210)
    at org.scalatest.BeforeAndAfterAll.run$(BeforeAndAfterAll.scala:208)
    at UnitSpecs.ControllerSpecs.AnswerControllerUnitSpec.org$scalatestplus$play$BaseOneAppPerSuite$$super$run(AnswerControllerUnitSpec.scala:32)
    at org.scalatestplus.play.BaseOneAppPerSuite.run(BaseOneAppPerSuite.scala:46)
    at org.scalatestplus.play.BaseOneAppPerSuite.run$(BaseOneAppPerSuite.scala:41)
    at UnitSpecs.ControllerSpecs.AnswerControllerUnitSpec.run(AnswerControllerUnitSpec.scala:32)
    at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:45)
    at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13(Runner.scala:1340)
    at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$13$adapted(Runner.scala:1334)
    at scala.collection.immutable.List.foreach(List.scala:389)
    at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1334)
    at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24(Runner.scala:1031)
    at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24$adapted(Runner.scala:1010)
    at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1500)
    at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:1010)
    at org.scalatest.tools.Runner$.run(Runner.scala:850)
    at org.scalatest.tools.Runner.run(Runner.scala)
    at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2(ScalaTestRunner.java:133)
    at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:27)



Process finished with exit code 0

The error seem to be for line val logger = LoggerFactory.getLogger(this.getClass.getName) which to be honest doesn't make sense.

Manu Chadha
  • 15,555
  • 19
  • 91
  • 184

0 Answers0