I have following code like:
case req @ POST -> Root =>
req
.decode[UserCreateRequest] { decodedRequest =>
my stack is http4s + zio.
Ive added custom decoder for this case class where I have a line:
email <- Either.cond(StringValidator.isValidEmail(emailStr), Email(emailStr), DecodingFailure("email", c.history))
Posting invalid json, with invalid email returns me:
HTTP/1.1 422 Unprocessable Entity Content-Type: text/plain; charset=UTF-8 Date: Tue, 19 Jan 2021 16:46:27 GMT Content-Length: 29
The request body was invalid.
Response code: 422 (Unprocessable Entity); Time: 681ms; Content length: 29 bytes
which I would like to customize. In http4s code I see InvalidMessageBodyFailure. But I can not find in docs any info how to customize this response.
Any one maybe tried this already ?
thanks
edit:
sample UserCreateRequest:
final case class UserCreateRequest(
email: Email
)
final case class Email(value: String) extends AnyVal
json request:
{
"email": "myemail[at]gmail.com"
}
this can be achieved using such code:
(for {
decodedJson <- req.asJson.mapError { decodingError =>
HttpDecodingError(cause = decodingError.getMessage)
}
decodedRequest <- Task.fromEither(decodedJson.as[UserCreateRequest]).mapError { decodingError =>
HttpDecodingError(cause = decodingError.getMessage)
}
response <- UserService
.createNewUser(
decodedRequest.email
)
.bimap(
error => HttpGenericError(msg = error.msg, cause = error.cause.toString),
u => UserResponse(u.email.value)
)
} yield response).foldM((error: HttpError) => BadRequest(error), u => Ok(u))
but I wonder if it can be simplified, by some http4s core features, which are done already but not documented :)
You can directly return the
Status
from your API. i.e. you could construct anUnprocessableEntity
instance and use thewithXXX
methods to alter the response.Assuming some structure:
You can do: