Skip to content

Detailed error on Enum reads in enumeratum-play-json #409

Open
@Jenya95

Description

@Jenya95

Error message that enumeratum produces could be enriched with list of valid enum values.

For example if there is enum

sealed trait Operand extends EnumEntry with Hyphencase with Lowercase
object Operand       extends enumeratum.Enum[Operand] with PlayJsonEnum[Operand] {
  val values = findValues

  case object Equals    extends Operand
  case object Gt        extends Operand
  case object GtEq      extends Operand
  case object Lt        extends Operand
  case object LtEq      extends Operand
}

and some case class

case class Foo(operand: Operand)

object Foo {
  implicit val format: Format[Foo] = Json.format
}

Then attempt to parse the string

test("parse json string into case class with enum") {
    val jsonString = "{\"operand\":\"unknown\"}"
    Json.parse(jsonString).as[Foo]
}

will print error

JsResultException(errors:List((/operand,List(JsonValidationError(List(error.expected.validenumvalue),WrappedArray())))))

But what if we will extend EnumFormats and let it print error with details like:

JsResultException(errors:List((/operand,List(JsonValidationError(List(error.expected.validenumvalue),WrappedArray(valid enum values are: (equals, gt, gt-eq, lt, lt-eq, not-equals, in, not-in), but provided: unknown))))))

with change like this at EnumFormats:140:

  private def readsKeyAndExtracts[A <: EnumEntry](
      @deprecatedName(Symbol("enum")) e: Enum[A]
  )(extract: String => Option[A]): KeyReads[A] = new KeyReads[A] {
    def readKey(s: String): JsResult[A] = extract(s) match {
      case Some(obj) => JsSuccess(obj)
      case None =>
        JsError(
          JsonValidationError(
            "error.expected.validenumvalue",
            s"valid enum values are: (${e.values.map(_.entryName).mkString(", ")}), but provided: $s"
          )
        )
    }
  }

It can be disabled by default, configurable by some flag in trait PlayJsonEnum.

Does it make sense to implement?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions