summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Checkoway <dcheckoway@gmail.com>2015-04-25 10:52:31 -0400
committerDan Checkoway <dcheckoway@gmail.com>2015-04-27 07:25:49 -0400
commit4a6263779219fe498039b60fceefddfa4f1ba2a3 (patch)
treeac558972916ac38958ddcb0a6d07be575f46d0af
parentf56576932f98227ef1bd37981a46562d053f8409 (diff)
downloadspray-json-4a6263779219fe498039b60fceefddfa4f1ba2a3.tar.gz
spray-json-4a6263779219fe498039b60fceefddfa4f1ba2a3.tar.bz2
spray-json-4a6263779219fe498039b60fceefddfa4f1ba2a3.zip
Expose fieldName when able in deserialization errors
-rw-r--r--src/main/scala/spray/json/ProductFormats.scala6
-rw-r--r--src/main/scala/spray/json/package.scala6
-rw-r--r--src/test/scala/spray/json/ProductFormatsSpec.scala12
3 files changed, 19 insertions, 5 deletions
diff --git a/src/main/scala/spray/json/ProductFormats.scala b/src/main/scala/spray/json/ProductFormats.scala
index 9914b55..9e494ff 100644
--- a/src/main/scala/spray/json/ProductFormats.scala
+++ b/src/main/scala/spray/json/ProductFormats.scala
@@ -56,9 +56,11 @@ trait ProductFormats extends ProductFormatsInstances {
try reader.read(x.fields(fieldName))
catch {
case e: NoSuchElementException =>
- deserializationError("Object is missing required member '" + fieldName + "'", e)
+ deserializationError("Object is missing required member '" + fieldName + "'", e, fieldName :: Nil)
+ case DeserializationException(msg, cause, fieldNames) =>
+ deserializationError(msg, cause, fieldName :: fieldNames)
}
- case _ => deserializationError("Object expected in field '" + fieldName + "'")
+ case _ => deserializationError("Object expected in field '" + fieldName + "'", fieldNames = fieldName :: Nil)
}
protected def extractFieldNames(classManifest: ClassManifest[_]): Array[String] = {
diff --git a/src/main/scala/spray/json/package.scala b/src/main/scala/spray/json/package.scala
index fe37c8b..f79b99e 100644
--- a/src/main/scala/spray/json/package.scala
+++ b/src/main/scala/spray/json/package.scala
@@ -20,7 +20,7 @@ package object json {
type JsField = (String, JsValue)
- def deserializationError(msg: String, cause: Throwable = null) = throw new DeserializationException(msg, cause)
+ def deserializationError(msg: String, cause: Throwable = null, fieldNames: List[String] = Nil) = throw new DeserializationException(msg, cause, fieldNames)
def serializationError(msg: String) = throw new SerializationException(msg)
def jsonReader[T](implicit reader: JsonReader[T]) = reader
@@ -32,7 +32,7 @@ package object json {
package json {
- class DeserializationException(msg: String, cause: Throwable = null) extends RuntimeException(msg, cause)
+ case class DeserializationException(msg: String, cause: Throwable = null, fieldNames: List[String] = Nil) extends RuntimeException(msg, cause)
class SerializationException(msg: String) extends RuntimeException(msg)
private[json] class PimpedAny[T](any: T) {
@@ -44,4 +44,4 @@ package json {
def asJson: JsValue = parseJson
def parseJson: JsValue = JsonParser(string)
}
-} \ No newline at end of file
+}
diff --git a/src/test/scala/spray/json/ProductFormatsSpec.scala b/src/test/scala/spray/json/ProductFormatsSpec.scala
index a290604..ba9d907 100644
--- a/src/test/scala/spray/json/ProductFormatsSpec.scala
+++ b/src/test/scala/spray/json/ProductFormatsSpec.scala
@@ -23,6 +23,7 @@ class ProductFormatsSpec extends Specification {
case class Test0()
case class Test2(a: Int, b: Option[Double])
case class Test3[A, B](as: List[A], bs: List[B])
+ case class Test4(t2: Test2)
case class TestTransient(a: Int, b: Option[Double]) {
@transient var c = false
}
@@ -35,6 +36,7 @@ class ProductFormatsSpec extends Specification {
implicit val test0Format = jsonFormat0(Test0)
implicit val test2Format = jsonFormat2(Test2)
implicit def test3Format[A: JsonFormat, B: JsonFormat] = jsonFormat2(Test3.apply[A, B])
+ implicit def test4Format = jsonFormat1(Test4)
implicit def testTransientFormat = jsonFormat2(TestTransient)
implicit def testStaticFormat = jsonFormat2(TestStatic)
implicit def testMangledFormat = jsonFormat1(TestMangled)
@@ -71,6 +73,16 @@ class ProductFormatsSpec extends Specification {
"throw a DeserializationException if the JsValue is not a JsObject" in (
JsNull.convertTo[Test2] must throwA(new DeserializationException("Object expected in field 'a'"))
)
+ "expose the fieldName in the DeserializationException when able" in {
+ JsNull.convertTo[Test2] must throwA[DeserializationException].like {
+ case DeserializationException(_, _, fieldNames) => fieldNames mustEqual "a" :: Nil
+ }
+ }
+ "expose all gathered fieldNames in the DeserializationException" in {
+ JsObject("t2" -> JsObject("a" -> JsString("foo"))).convertTo[Test4] must throwA[DeserializationException].like {
+ case DeserializationException(_, _, fieldNames) => fieldNames mustEqual "t2" :: "a" :: Nil
+ }
+ }
}
"A JsonProtocol mixing in NullOptions" should {