Skip to content

One way that error messages could be more helpful #488

@brunchboy

Description

@brunchboy

Opening this by request of @GreyCat. Last night I wasted a lot of time because in an earlier version of this line: https://github.com/Deep-Symmetry/beat-link/blob/5da596c526768a3f6df40d044754845f6397dc67/kaitai/pdb.ksy#L211 I had forgotten that the ksc expression language uses and for conjoining boolean expressions, rather than && like most C-derived languages I generally use, so I had && instead of the and there. Unfortunately, the error message I received was:

End:1:35 ..."&& (num_ro"

That gave me no context whatsoever, not even the line number. It would have been far more helpful to say something like:

Unrecognized token "&&" at line 211, column 44.

That would have at least sent me to the manual to look for the right thing. Since this is probably a common mistake, you could even be extra nice and say something like:

Unrecognized token "&&" at line 211, column 44, did you mean "and"?

Something similar could be offered for || and or.

Even looking at the exception, now that I know that trick, did not help:

Exception in thread "main" io.kaitai.struct.exprlang.Expressions$ParseException: End:1:35 ..."&& (num_ro"
	at io.kaitai.struct.exprlang.Expressions$.realParse(Expressions.scala:178)
	at io.kaitai.struct.exprlang.Expressions$.parse(Expressions.scala:170)
	at io.kaitai.struct.format.InstanceSpec$.$anonfun$fromYaml$1(InstanceSpec.scala:44)
	at scala.Option.map(Option.scala:146)
	at io.kaitai.struct.format.InstanceSpec$.fromYaml(InstanceSpec.scala:44)
	at io.kaitai.struct.format.ClassSpec$.$anonfun$instancesFromYaml$1(ClassSpec.scala:211)
	at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
	at scala.collection.MapLike$MappedValues.$anonfun$foreach$3(MapLike.scala:253)
	at scala.collection.TraversableLike$WithFilter.$anonfun$foreach$1(TraversableLike.scala:789)
	at scala.collection.immutable.Map$Map3.foreach(Map.scala:176)
	at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:788)
	at scala.collection.MapLike$MappedValues.foreach(MapLike.scala:253)
	at scala.collection.TraversableLike.map(TraversableLike.scala:234)
	at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
	at scala.collection.AbstractTraversable.map(Traversable.scala:104)
	at io.kaitai.struct.format.ClassSpec$.instancesFromYaml(ClassSpec.scala:207)
	at io.kaitai.struct.format.ClassSpec$.fromYaml(ClassSpec.scala:107)
	at io.kaitai.struct.format.ClassSpec$.$anonfun$typesFromYaml$1(ClassSpec.scala:201)
	at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
	at scala.collection.immutable.HashMap$HashMap1.foreach(HashMap.scala:231)
	at scala.collection.immutable.HashMap$HashTrieMap.foreach(HashMap.scala:462)
	at scala.collection.TraversableLike.map(TraversableLike.scala:234)
	at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
	at scala.collection.AbstractTraversable.map(Traversable.scala:104)
	at io.kaitai.struct.format.ClassSpec$.typesFromYaml(ClassSpec.scala:199)
	at io.kaitai.struct.format.ClassSpec$.fromYaml(ClassSpec.scala:103)
	at io.kaitai.struct.format.ClassSpec$.fromYaml(ClassSpec.scala:224)
	at io.kaitai.struct.formats.JavaKSYParser$.fileNameToSpec(JavaKSYParser.scala:29)
	at io.kaitai.struct.formats.JavaKSYParser$.localFileToSpecs(JavaKSYParser.scala:18)
	at io.kaitai.struct.JavaMain.compileOneInput(JavaMain.scala:237)
	at io.kaitai.struct.JavaMain.$anonfun$run$1(JavaMain.scala:212)
	at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:234)
	at scala.collection.immutable.List.foreach(List.scala:389)
	at scala.collection.TraversableLike.map(TraversableLike.scala:234)
	at scala.collection.TraversableLike.map$(TraversableLike.scala:227)
	at scala.collection.immutable.List.map(List.scala:295)
	at io.kaitai.struct.JavaMain.run(JavaMain.scala:210)
	at io.kaitai.struct.JavaMain$.main(JavaMain.scala:201)
	at io.kaitai.struct.JavaMain.main(JavaMain.scala)

In the end, I spent a long time trying to separate the expression into simpler sub-expressions using additional parse instances to try to figure out what was going on, and eventually slapped my forehead and vented in the Gitter chat. Hopefully we can spare future adopters such fun. 😄

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions