diff options
author | Mathias <mathias@decodified.com> | 2015-05-06 09:35:52 +0200 |
---|---|---|
committer | Mathias <mathias@decodified.com> | 2015-05-06 09:35:52 +0200 |
commit | 8467f8698a3abef894b0bb85dcfe54c2bab7a47c (patch) | |
tree | ac558972916ac38958ddcb0a6d07be575f46d0af | |
parent | f56576932f98227ef1bd37981a46562d053f8409 (diff) | |
parent | 4a6263779219fe498039b60fceefddfa4f1ba2a3 (diff) | |
download | spray-json-8467f8698a3abef894b0bb85dcfe54c2bab7a47c.tar.gz spray-json-8467f8698a3abef894b0bb85dcfe54c2bab7a47c.tar.bz2 spray-json-8467f8698a3abef894b0bb85dcfe54c2bab7a47c.zip |
Merge pull request #153 from layerhq/expose-field-name-in-deserialization-errors
Expose fieldName when able in deserialization errors
-rw-r--r-- | src/main/scala/spray/json/ProductFormats.scala | 6 | ||||
-rw-r--r-- | src/main/scala/spray/json/package.scala | 6 | ||||
-rw-r--r-- | src/test/scala/spray/json/ProductFormatsSpec.scala | 12 |
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 { |