enumeratum icon indicating copy to clipboard operation
enumeratum copied to clipboard

Detailed error on Enum reads in enumeratum-play-json

Open Jenya95 opened this issue 1 year ago • 3 comments

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?

Jenya95 avatar Nov 17 '24 18:11 Jenya95

I think this sounds like a nice enhancement.

lloydmeta avatar Nov 23 '24 03:11 lloydmeta

You should fork and push the branch to your fork then send a PR here.

lloydmeta avatar Nov 24 '24 11:11 lloydmeta

@lloydmeta PR at https://github.com/lloydmeta/enumeratum/pull/411

Jenya95 avatar Nov 24 '24 18:11 Jenya95