decodeValidationReason
Decodes one RequestValidationException reason. This is what requestValidation does internally for every entry of errors[]. It is exposed so a mapping that needs a shape requestValidation cannot produce — a typed errors[] element, differently named members, an extra member per entry — can still read ValidationReason.pointer/ValidationReason.detail back out of a reason built by invalidField/invalidFields, instead of re-inventing the encoding.
See also
Samples
install(RequestValidation) {
validate<String> { body ->
if (body.isBlank()) {
invalidFields(
"#/age" to "must be a positive integer",
"#/profile/color" to "must be 'green', 'red' or 'blue'",
)
} else {
ValidationResult.Valid
}
}
}
install(StatusPages) {
problemDetails {
// Bypasses requestValidation(): its errors[] shape is fixed to detail/pointer, renameable
// but not restructured. decodeValidationReason() still reads the pointer/detail that
// invalidFields() encoded. encodeToProblemValue() turns the typed entry into a ProblemValue.
map<RequestValidationException> { _, cause ->
Problem(
type = ValidationError.typeUri,
status = ValidationError.status,
title = ValidationError.title,
extensions =
mapOf(
"errors" to
ProblemArray(
cause.reasons.map { reason ->
val decoded = decodeValidationReason(reason)
Json.encodeToProblemValue(
ValidationErrorEntry(
code = "VALIDATION_FAILED",
field = decoded.pointer,
message = decoded.detail,
),
)
},
),
),
)
}
}
}
routing {
post("/customers") {
call.respond(call.receive<String>())
}
}Content copied to clipboard