konform-kt / konform

Portable validations for Kotlin
https://www.konform.io
MIT License
652 stars 39 forks source link

Getting all errors for a result #3

Closed oripwk closed 4 years ago

oripwk commented 6 years ago

Currently a ValidationResult<T> can be used to get errors for a specific field:

result[UserProfile::fullName]

Is there any way to get a map of all errors for a given validation (not a separate list for every field)?

nlochschmidt commented 6 years ago

Not right now.

The main issue is, that I am unsure what the most useful representation would be. One Possibility would be the current internal representation which is Map<List<String>, List<String>>. E.g.

mapOf(
  listOf("user", "fullName") to listOf("is required"),
  listOf("user", "age") to listOf("must be at least 18 years old") 

Another would be a Map<String, Any> where Any might be another Map<String, Any> or a List<String> e.g.

mapOf(
  "user" to mapOf(
    "fullName" to listOf("is required"),
    "age" to listOf("must be at least 18 years old")))

Yet another idea is to have KProperty instead of String as key and also an ValidationError class.

wiltonlazary commented 6 years ago

Let folks have access to error map as it is, it is easy to transform to json actually.

@Suppress("UNCHECKED_CAST")
fun <T> Any?.cast(): T = this as T

class ModelValidationException(
    val source: Any,
    val result: Invalid<Any>,
    val tag: String = source::class.simpleName!!
) : RuntimeException() {
    companion object {
        val errorsField = Invalid::class.java.getDeclaredField("errors")

        init {
            errorsField.isAccessible = true
        }
    }

    fun toJson(): JsonElement {
        val errors = errorsField.get(result).cast<Map<List<String>, List<String>>>()

        return gson.toJsonTree(mapOf(
            "tag" to tag,
            "errors" to errors
        ))
    }

    override fun toString(): String {
        return toJson().toString()
    }

    override val message: String?
        get() = toString()
}
ghost commented 5 years ago

This to me is the single biggest blocker to making this useable in a nice way.

I use various methods of validation, and I encapsulate them in my own interfaces. I think validation is a core part of your logic and should not be embedded in your peripheral http/server frameworks.

For the same reason, I would never expose the data classes or exceptions of an internally used framework in my own API. I will always translate them to my own data types.

Right now, if I wanted to translate the error messages raised by this framework into my own errors, I would have to do some nasty iteration involving reflection on my own classes and their fields.

Please expose the collection of all errors (Map<List<String>, List<String>>).

jeminglin commented 5 years ago

Seems I am not alone, ;)

silversoul93 commented 4 years ago

18

nlochschmidt commented 4 years ago

Version 0.2.0 now exposes the errors in the ValidationResult.

The readme has been updated as well.