Sunday, 15 January 2012

How to report parsing errors when using JSON.parseFull with Scala -



How to report parsing errors when using JSON.parseFull with Scala -

when app fed syntactically wrong json want able study error user useful detail allow problem area located.

so in illustration j none because of trailing comma after "file1". there way obtain details of lastly parse error?

val badsyntax = """ { "menu1": { "id": "file1", "value": "file1", }, "menu2": { "id": "file2", "value": "file2", } }""" val j = json.parsefull(badsyntax)

when parse error, utilize json.lastnosuccess lastly error. of type json.nosuccess of thare 2 subclasses, json.error , json.failure, both containing msg: string fellow member detailing error. note json.lastnosuccess not thread safe (it mere global variable) , deprecated (bound disappear in scala 2.11)

update: apparently, wrong not beingness thread-safe: indeed not thread-safe before scala 2.10, lastnosuccess backed thread-local variable (and safe utilize in multi-threaded context). after seing this, you'd forgiven think long read right after parsing failure in same thread 1 used parsing (the thread called parsefull), work expected. unfortunately, during refactor changed how utilize lastnosuccess internally within parsers.phrase (which called json.parsefull. see https://github.com/scala/scala/commit/1a4faa92faaf495f75a6dd2c58376f6bb3fbf44c since refactor, lastnosuccess reset none @ end of parsers.phrase. no problem in parsers in general, lastnosuccess used temporary value returned result of parsers.phrase anyway. the problem here don't phone call parsers.phrase, json.parsefull, drops error info (see case none => none within method json.parseraw @ https://github.com/scala/scala/blob/v2.10.0/src/library/scala/util/parsing/json/json.scala). fact json.parsefull drops error info circumvented prior scala 2.10 straight reading json.lastnosuccess advised before, value reset @ end of parsers.phrase, there not much can error info out of json.

any solution? yes. can create own version of json not drop error information:

import util.parsing.json._ object myjson extends parser { def parseraw(input : string) : either[nosuccess, jsontype] = { phrase(root)(new lexical.scanner(input)) match { case success(result, _) => right(result) case ns: nosuccess => left(ns) } } def parsefull(input: string): either[nosuccess, any] = { parseraw(input).right.map(resolvetype) } def resolvetype(input: any): = input match { case jsonobject(data) => data.transform { case (k,v) => resolvetype(v) } case jsonarray(data) => data.map(resolvetype) case x => x } }

i changed option either result type, can homecoming parsing errors left. test in repl:

scala> myjson.parsefull("[1,2,3]") res11: either[myjson.nosuccess,any] = right(list(1.0, 2.0, 3.0)) scala> myjson.parsefull("[1,2,3") res12: either[myjson.nosuccess,any] = left([1.7] failure: end of input [1,2,3 ^)

json scala

No comments:

Post a Comment