aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorJack Koenig2020-09-04 17:20:01 -0700
committerGitHub2020-09-05 00:20:01 +0000
commit47c81ee3e68c96e94dafa389cb53b162e996a4df (patch)
treee976c5b9adcec16a6215863eda811617c64c5f1c /src/main
parentb25c90f27bcf5ff61d7f0d16fb274759a628a500 (diff)
Better error messages for unserializable annotations (#1885)
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/firrtl/annotations/AnnotationUtils.scala10
-rw-r--r--src/main/scala/firrtl/annotations/JsonProtocol.scala15
2 files changed, 23 insertions, 2 deletions
diff --git a/src/main/scala/firrtl/annotations/AnnotationUtils.scala b/src/main/scala/firrtl/annotations/AnnotationUtils.scala
index a1276e0e..eccb4e13 100644
--- a/src/main/scala/firrtl/annotations/AnnotationUtils.scala
+++ b/src/main/scala/firrtl/annotations/AnnotationUtils.scala
@@ -18,6 +18,16 @@ case class AnnotationClassNotFoundException(className: String)
extends FirrtlUserException(
s"Annotation class $className not found! Please check spelling and classpath"
)
+class UnserializableAnnotationException private (msg: String) extends FirrtlUserException(msg)
+object UnserializableAnnotationException {
+ private def toMessage(pair: (Annotation, Throwable)): String =
+ s"Failed to serialiaze annotation of type ${pair._1.getClass.getName} because '${pair._2.getMessage}'"
+ private[firrtl] def apply(badAnnos: Seq[(Annotation, Throwable)]) = {
+ require(badAnnos.nonEmpty)
+ val msg = badAnnos.map(toMessage).mkString("\n ", "\n ", "\n")
+ new UnserializableAnnotationException(msg)
+ }
+}
object AnnotationUtils {
diff --git a/src/main/scala/firrtl/annotations/JsonProtocol.scala b/src/main/scala/firrtl/annotations/JsonProtocol.scala
index 0ef8b020..144cd894 100644
--- a/src/main/scala/firrtl/annotations/JsonProtocol.scala
+++ b/src/main/scala/firrtl/annotations/JsonProtocol.scala
@@ -10,7 +10,7 @@ import scala.util.{Failure, Try}
import org.json4s._
import org.json4s.native.JsonMethods._
import org.json4s.native.Serialization
-import org.json4s.native.Serialization.{read, writePretty}
+import org.json4s.native.Serialization.{read, write, writePretty}
trait HasSerializationHints {
// For serialization of complicated constructor arguments, let the annotation
@@ -220,6 +220,13 @@ object JsonProtocol {
/** Serialize annotations to a String for emission */
def serialize(annos: Seq[Annotation]): String = serializeTry(annos).get
+ private def findUnserializeableAnnos(
+ annos: Seq[Annotation]
+ )(
+ implicit formats: Formats
+ ): Seq[(Annotation, Throwable)] =
+ annos.map(a => a -> Try(write(a))).collect { case (a, Failure(e)) => (a, e) }
+
def serializeTry(annos: Seq[Annotation]): Try[String] = {
val tags = annos
.flatMap({
@@ -229,7 +236,11 @@ object JsonProtocol {
.distinct
implicit val formats = jsonFormat(tags)
- Try(writePretty(annos))
+ Try(writePretty(annos)).recoverWith {
+ case e: org.json4s.MappingException =>
+ val badAnnos = findUnserializeableAnnos(annos)
+ Failure(if (badAnnos.isEmpty) e else UnserializableAnnotationException(badAnnos))
+ }
}
def deserialize(in: JsonInput): Seq[Annotation] = deserializeTry(in).get