I'm currently creating an application in Quarkus, using Kotlin. I'm trying to create a simple users endpoint using RestEasy, Panache, and Hibernate. My challenge right now is that exception handling is not correctly done. I want to display a correct and understandable message to the user when the request isn't valid.
This is my UserResource for the createUser POST request:
@POST
@Transactional
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
fun createUser(@Valid user: User) : CreateUserResponse =
try {
userRepository.persist(user)
CreateUserSuccess(user)
} catch (e: Exception) {
CreateUserFailure(e)
}
And this is my User entity:
@Entity
data class User (
@Id
@GeneratedValue(generator = "UUID")
var id: UUID? = UUID.randomUUID(),
@NotBlank
var fullName: String,
@Email
@NotBlank(message = "email may not be blank")
var email: String,
@CreationTimestamp
var createdAt: LocalDateTime? = null,
@UpdateTimestamp
var updatedAt: LocalDateTime? = null,
)
And for the completeness, this is my UserRepository:
@ApplicationScoped
class UserRepository : PanacheRepository<User>
Creating a user does work, when I'm sure the request is valid. But I'd also like to make sure invalid requests get handled nicely when the request isn't valid. This is the response I'm getting right now when I hit the createUser endpoint:
com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of
`com.fortuneapp.backend.application.domain.core.models.entities.User`, problem: Parameter specified as non-null is null:
method com.fortuneapp.backend.application.domain.core.models.entities.User.<init>, parameter email
at [Source: (io.quarkus.vertx.http.runtime.VertxInputStream); line: 3, column: 1]
What am I missing here?
You are having an issue with the nulatibility of your properties, as you can see even tough you are defining var
properties some of them are not nullable ?
so because you are deserializing a json message, the input of the rest services, Jackson is not being able to create the new instance of your model class user
because some of the required fields are not present.
This is similar to when you try to create a new object but do not provide the required arguments in the constructor.
There is some recommendations to work with kotlin an Jax-RS and Hibernate-Panache here https://quarkus.io/guides/kotlin.
What you are trying to archive its perfectly possible but if you want to use you Entity as request body, you must make all the fields nullable, otherwise the underlying Json serializer will not be able to create the new instance of your model to pass the @Valid
validations and generate the constraint violation report.
You have some options here.
If you have more doubts i can provide an example.