diff options
| author | Jack Koenig | 2018-03-22 11:53:51 -0700 |
|---|---|---|
| committer | GitHub | 2018-03-22 11:53:51 -0700 |
| commit | ebb6847e9d01b424424ae11a0067448a4094e46d (patch) | |
| tree | fc87aa9d7b7d437914f6a4c9e20487c0973a1fc3 /src/main/scala/firrtl/annotations/JsonProtocol.scala | |
| parent | 6ea4ac666e4ce8dfaca1545660f372fccff610f5 (diff) | |
Better bad annotation file error reporting (#771)
* Propagate exceptions from JsonProtocol deserialization
* Add AnnotationFileNotFoundException for better error reporting
* Add AnnotationClassNotFoundException for better error reporting
* Better propagate JSON parsing errors
Also report the file if there is a error deserializing a JSON file
* Make exception for non-array JSON file more explicit
Diffstat (limited to 'src/main/scala/firrtl/annotations/JsonProtocol.scala')
| -rw-r--r-- | src/main/scala/firrtl/annotations/JsonProtocol.scala | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/src/main/scala/firrtl/annotations/JsonProtocol.scala b/src/main/scala/firrtl/annotations/JsonProtocol.scala index 5005ccb0..7b2617f5 100644 --- a/src/main/scala/firrtl/annotations/JsonProtocol.scala +++ b/src/main/scala/firrtl/annotations/JsonProtocol.scala @@ -2,7 +2,7 @@ package firrtl package annotations -import scala.util.Try +import scala.util.{Try, Failure} import org.json4s._ import org.json4s.native.JsonMethods._ @@ -13,18 +13,6 @@ import firrtl.ir._ import firrtl.Utils.error object JsonProtocol { - - // Helper for error messages - private def prettifyJsonInput(in: JsonInput): String = { - def defaultToString(base: String, obj: Any): String = s"$base@${obj.hashCode.toHexString}" - in match { - case FileInput(file) => file.toString - case StringInput(o) => defaultToString("String", o) - case ReaderInput(o) => defaultToString("Reader", o) - case StreamInput(o) => defaultToString("Stream", o) - } - } - class TransformClassSerializer extends CustomSerializer[Class[_ <: Transform]](format => ( { case JString(s) => Class.forName(s).asInstanceOf[Class[_ <: Transform]] }, { case x: Class[_] => JString(x.getName) } @@ -66,19 +54,31 @@ object JsonProtocol { def deserialize(in: JsonInput): Seq[Annotation] = deserializeTry(in).get def deserializeTry(in: JsonInput): Try[Seq[Annotation]] = Try({ - def throwError() = throw new InvalidAnnotationFileException(prettifyJsonInput(in)) val parsed = parse(in) val annos = parsed match { case JArray(objs) => objs - case _ => throwError() + case x => throw new InvalidAnnotationJSONException( + s"Annotations must be serialized as a JArray, got ${x.getClass.getSimpleName} instead!") } // Gather classes so we can deserialize arbitrary Annotations val classes = annos.map({ case JObject(("class", JString(c)) :: tail) => c - case _ => throwError() + case obj => throw new InvalidAnnotationJSONException(s"Expected field 'class' not found! $obj") }).distinct val loaded = classes.map(Class.forName(_).asInstanceOf[Class[_ <: Annotation]]) implicit val formats = jsonFormat(loaded) read[List[Annotation]](in) - }) + }).recoverWith { + // Translate some generic errors to specific ones + case e: java.lang.ClassNotFoundException => + Failure(new AnnotationClassNotFoundException(e.getMessage)) + case e: org.json4s.ParserUtil.ParseException => + Failure(new InvalidAnnotationJSONException(e.getMessage)) + }.recoverWith { // If the input is a file, wrap in InvalidAnnotationFileException + case e => in match { + case FileInput(file) => + Failure(new InvalidAnnotationFileException(file, e)) + case _ => Failure(e) + } + } } |
