Elide handles errors as defined in specification of the endpoint format (JSONAPI or GraphQL). Where possible Elide will already create meaningful errors for you. In cases such as custom validations or data store related exceptions you might want to customize the behavior.
Elide will perform classic bean validation of your entity classes by making use of the Hibernate validator. This
basically covers all javax.validation
annotations.
Since classic bean validation can only perform a subset of validations, you might use pre-security or pre-commit
lifecycle hooks to perform additional checks. If you want to give the user proper error response here, you should
throw a CustomErrorException
.
A CustomErrorException
can contain one or multiple errors in the errorObjects
field. Use the ErrorOjectsBuilder
to create them.
In some scenarios, user interaction might cause exceptions in the application that are beyond your control. It might be
desired to remap these exceptions in order to return the client meaningful error codes. This can be achieved by
configuring Elide to use a custom implementation of an ErrorMapper
.
A common example for this case are constraint violations in the JPA datastore. If your database encounters a constraint
violation hibernate will throw a (nested) ConstraintViolationException
containing the name of the violated constraint.
By default Elide would throw a generic error message with the description “Could not execute statement”.
However, the name of the violated constraint can be used to derive a proper error message.
Here is an example implementation written in Kotlin:
@Component
class HibernateErrorMapper : ErrorMapper {
override fun map(origin: Exception): CustomErrorException? {
val error = findHibernateConstraintViolationExceptionOrNull(origin) ?: return null
return when (error.constraintName) {
"datasource_name_uindex" -> Errors.DATASOURCE_NAME_NOT_UNIQUE.asElideError()
else -> null
}
}
fun findHibernateConstraintViolationExceptionOrNull(exception: Exception, maxDepth: Int = 5): ConstraintViolationException? =
if (maxDepth <= 0) {
null
} else {
val cause = exception.cause
when {
exception is ConstraintViolationException -> exception
cause is Exception -> findHibernateConstraintViolationExceptionOrNull(cause, maxDepth - 1)
else -> null
}
}
}