Closed aboisvert closed 3 months ago
Of course the moment I file an issue, I discover there's an optional trace
argument to upickle.default.read
. D'oh.
What API are you using? It's meant to give you the character offset that the failure occurred even without trace. Trace is optional only if you want the pretty JSON path
@ upickle.default.read[Map[String, Seq[String]]]("""{"hello": "world"}""")
upickle.core.AbortException: expected sequence got string at index 10
ujson.CharParser$$anonfun$reject$1.applyOrElse(CharParser.scala:344)
ujson.CharParser$$anonfun$reject$1.applyOrElse(CharParser.scala:342)
scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:35)
ujson.CharParser.parseNested(CharParser.scala:379)
ujson.CharParser.parseTopLevel0(CharParser.scala:324)
ujson.CharParser.parseTopLevel(CharParser.scala:308)
ujson.CharParser.parse(CharParser.scala:59)
ujson.StringParser$.transform(StringParser.scala:28)
ujson.StringParser$.transform(StringParser.scala:27)
ujson.Readable$fromTransformer.transform(Readable.scala:13)
upickle.Api.$anonfun$read$1(Api.scala:37)
upickle.core.TraceVisitor$.withTrace(TraceVisitor.scala:18)
upickle.Api.read(Api.scala:37)
upickle.Api.read$(Api.scala:36)
upickle.default$.read(Api.scala:157)
ammonite.$sess.cmd3$.<clinit>(cmd3.sc:1)
upickle.core.Abort: expected sequence got string
upickle.core.SimpleVisitor.visitString(SimpleVisitor.scala:14)
upickle.core.SimpleVisitor.visitString$(SimpleVisitor.scala:13)
upickle.implicits.Readers$$anon$24.visitString(Readers.scala:280)
ujson.CharParser.visitString(CharParser.scala:617)
ujson.CharParser.parseStringValue(CharParser.scala:586)
ujson.CharParser.parseNested(CharParser.scala:379)
ujson.CharParser.parseTopLevel0(CharParser.scala:324)
ujson.CharParser.parseTopLevel(CharParser.scala:308)
ujson.CharParser.parse(CharParser.scala:59)
ujson.StringParser$.transform(StringParser.scala:28)
ujson.StringParser$.transform(StringParser.scala:27)
ujson.Readable$fromTransformer.transform(Readable.scala:13)
upickle.Api.$anonfun$read$1(Api.scala:37)
upickle.core.TraceVisitor$.withTrace(TraceVisitor.scala:18)
upickle.Api.read(Api.scala:37)
upickle.Api.read$(Api.scala:36)
upickle.default$.read(Api.scala:157)
ammonite.$sess.cmd3$.<clinit>(cmd3.sc:1)
@ upickle.default.read[Map[String, Seq[String]]]("""{"hello": "world"}""", trace = true)
upickle.core.TraceVisitor$TraceException: $['hello']
upickle.core.AbortException: expected sequence got string at index 10
ujson.CharParser$$anonfun$reject$1.applyOrElse(CharParser.scala:344)
ujson.CharParser$$anonfun$reject$1.applyOrElse(CharParser.scala:342)
scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:35)
ujson.CharParser.parseNested(CharParser.scala:379)
ujson.CharParser.parseTopLevel0(CharParser.scala:324)
ujson.CharParser.parseTopLevel(CharParser.scala:308)
ujson.CharParser.parse(CharParser.scala:59)
ujson.StringParser$.transform(StringParser.scala:28)
ujson.StringParser$.transform(StringParser.scala:27)
ujson.Readable$fromTransformer.transform(Readable.scala:13)
upickle.Api.$anonfun$read$1(Api.scala:37)
upickle.core.TraceVisitor$.withTrace(TraceVisitor.scala:21)
upickle.Api.read(Api.scala:37)
upickle.Api.read$(Api.scala:36)
upickle.default$.read(Api.scala:157)
ammonite.$sess.cmd4$.<clinit>(cmd4.sc:1)
upickle.core.Abort: expected sequence got string
upickle.core.SimpleVisitor.visitString(SimpleVisitor.scala:14)
upickle.core.SimpleVisitor.visitString$(SimpleVisitor.scala:13)
upickle.implicits.Readers$$anon$24.visitString(Readers.scala:280)
upickle.core.Visitor$Delegate.visitString(Visitor.scala:156)
ujson.CharParser.visitString(CharParser.scala:617)
ujson.CharParser.parseStringValue(CharParser.scala:586)
ujson.CharParser.parseNested(CharParser.scala:379)
ujson.CharParser.parseTopLevel0(CharParser.scala:324)
ujson.CharParser.parseTopLevel(CharParser.scala:308)
ujson.CharParser.parse(CharParser.scala:59)
ujson.StringParser$.transform(StringParser.scala:28)
ujson.StringParser$.transform(StringParser.scala:27)
ujson.Readable$fromTransformer.transform(Readable.scala:13)
upickle.Api.$anonfun$read$1(Api.scala:37)
upickle.core.TraceVisitor$.withTrace(TraceVisitor.scala:21)
upickle.Api.read(Api.scala:37)
upickle.Api.read$(Api.scala:36)
upickle.default$.read(Api.scala:157)
ammonite.$sess.cmd4$.<clinit>(cmd4.sc:1)
@lihaoyi said:
What API are you using? It's meant to give you the character offset that the failure occurred even without trace. Trace is optional only if you want the pretty JSON path
I was reading the JSON data into an AST instead of reading directly from a file, e.g.,
val data = os.read(fileName)
val jsonAst = ujson.read(data)
upickle.default.read[MyType](jsonAst)
Especially for the case of unmarshalling from an AST, it would be generally helpful to provide a json path where the error occurred, assuming trace is on. (This would complement the index position in case reading directly from a file/stream)
If this is desirable, I could see about creating a PR for this.
When upickle fails to read to a json document into an object tree, the errors don't provide much context into where in the json/class trees the error happens.
Example:
This is bothersome for large documents and complex class hierarchies because it doesn't provide any insight into where the issue lies, even if the document passes json-schema validation, for example.
Are there plans to improve this? Or maybe some configuration option that I missed? Thanks!