Skip to content

MessagePack Fallback decoder uses path label "either" in error, and the size error says "1 or 2" instead of "2 or 3" #1101

Description

@haskiindahouse

Two small but confusing copy-paste leftovers in the MsgPack decodeFallback:

  1. When an unexpected field name is encountered inside a Fallback structure, the error path appends "either" instead of "fallback". Looks like a copy from decodeEither right above it.
  2. When the array header size is unrecognized, the error message says "Expected 1 or 2 elements but received $size", but the code actually handles size 2 (Left/Right) and size 3 (Both). The "1 or 2" wording is misleading.

Source

private def decodeFallback[A, B](path: Path, left: Schema[A], right: Schema[B], fullDecode: Boolean): Result[Fallback[A, B]] =
Try(unpacker.unpackArrayHeader()).fold(
err => fail(path, s"Error parsing Fallback structure: ${err.getMessage}"),
size =>
if (size == 2) {
decodeString(path :+ "fallback").flatMap {
case "left" => decodeValue(path :+ "fallback:left", left).map(Fallback.Left(_))
case "right" => decodeValue(path :+ "fallback:right", right).map(Fallback.Right(_))
case str => fail(path :+ "either", s"Unexpected field name: $str")
}
} else if (size == 3) {
unpacker.skipValue()
if (fullDecode)
decodeValue(path :+ "fallback:left", left).flatMap(l => decodeValue(path :+ "fallback:right", right).map(r => Fallback.Both(l, r)))
else {
val res = decodeValue(path :+ "fallback:left", left).map(Fallback.Left(_))
unpacker.skipValue()
res
}
} else {
fail(path :+ "fallback", s"Expected 1 or 2 elements but received $size.")
}
)

private def decodeFallback[A, B](path: Path, left: Schema[A], right: Schema[B], fullDecode: Boolean): Result[Fallback[A, B]] =
  Try(unpacker.unpackArrayHeader()).fold(
    err => fail(path, s"Error parsing Fallback structure: ${err.getMessage}"),
    size =>
      if (size == 2) {
        decodeString(path :+ "fallback").flatMap {
          case "left"  => decodeValue(path :+ "fallback:left", left).map(Fallback.Left(_))
          case "right" => decodeValue(path :+ "fallback:right", right).map(Fallback.Right(_))
          case str     => fail(path :+ "either", s"Unexpected field name: $str")  // <-- "either" should be "fallback"
        }
      } else if (size == 3) {
        // ...
      } else {
        fail(path :+ "fallback", s"Expected 1 or 2 elements but received $size.")  // <-- should be "2 or 3"
      }
  )

Expected

  • The path on the unexpected-field-name failure says fallback, matching the rest of the method.
  • The size-mismatch message reads "Expected 2 or 3 elements but received $size.".

Actual

Misleading "either" path on field-name failures, misleading "1 or 2" count in the size-error.

Happy to PR.

Versions

zio-schema-msg-pack at the SHA above (current main), Scala 3.8.3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions