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.