Skip to end of metadata
Go to start of metadata

Syncope's REST API propagates some exceptions to client side.
Actual exception mapping and possible improvements for CXF REST API migration are represented on this page.

Mapping exception to/from HTTP response

Actually service (core) propagates exceptions in syncopeClientError.jsp directly using http servlet response, client uses Spring handler (SyncopeClientErrorHandler) to get exception from HTTP response.
Suggestion: by CXF migration use CXF REST exception mappers for both sides: client and service. It makes code more harmonic and understandable.

Mapping exceptions to HTTP codes

Exception

Old Code

New Code

InvalidEntityException

BAD_REQUEST

BAD_REQUEST

NotFoundException

NOT_FOUND

NOT_FOUND

WorkflowException

BAD_REQUEST

BAD_REQUEST

PropagationException

BAD_REQUEST

BAD_REQUEST

SyncopeClientCompositeErrorException

BAD_REQUEST

BAD_REQUEST

MissingConfKeyException

NOT_FOUND

NOT_FOUND

InvalidSearchConditionException

BAD_REQUEST

BAD_REQUEST

UnauthorizedRoleException

BAD_REQUEST

FORBIDDEN

DataIntegrityViolationException (spring.dao)

BAD_REQUEST

CONFLICT

PersistenceException (javax)

BAD_REQUEST

INTERNAL_SERVER_ERROR

ConfigurationException (connid)

BAD_REQUEST

INTERNAL_SERVER_ERROR

All others

INTERNAL_SERVER_ERROR

INTERNAL_SERVER_ ERROR

Mapping from SyncopeClientCompositeErrorException on server side

Actually SyncopeClientCompositeErrorException is sent using:

  1. ExceptionType HTTP header containing exception type (enumeration SyncopeClientExceptionType)
  2. <ExceptionType>.element HTTP header as list of strings for error details (that are used to fill SyncopeClientException.elements)

For the CXF REST migration we will keep current propagation one to one and will add more verbose exception in HTTP body at the second step

Mapping to SyncopeClientCompositeException on client side SYNCOPE-303

Actually almost all exceptions with status BAD_REQUEST and NOT_FOUND are mapped to SyncopeClientCompositeErrorException on the client side.
It is absolutely OK for composite exceptions containing number of sub-exceptions (like validation and propagation), however for some single exceptions it makes more sense to map not to SyncopeClientCompositeErrorException, but directly to corresponded exception type.
Candidates are:

  • Deadlock
  • ExistingResource
  • DataIntegrityViolation
  • GenericPersistence
  • UnauthorizedRole

Proposed mapping makes exception processing more easy and effective.

Mapping low level exceptions in core SYNCOPE-304

Actually service layer processes three relative low level exceptions from persistence:

  • org.apache.ibatis.exceptions.PersistenceException;
  • org.springframework.orm.jpa.JpaSystemException;
  • javax.persistence.PersistenceException

Suggestion: abstract service implementation from persistence a little bit more and wrap these three exceptions in high level Syncope PersistenceException.
From my perspective it helps for the cases when Syncope will support alternative persistence technologies like Hibernate JPA, EclipseLink JPA or even LDAP, JCR, non-SQL DBs.

Checked vs Runtime exceptions

Accordingly Java Best Practices checked exceptions should be used only for conditions from which the caller can reasonably be expected to recover.
Runtime exceptions should be used for preconditions violation and for programming errors.
Candidates for checked exceptions are:

  • InvalidSearchConditionException
  • InvalidPasswordPolicySpecException

Candidates for runtime exceptions:

  • all Validation exceptions inherited from javax.validation.ValidationException
  • NotFoundException
  • MissingConfKeyException
  • AccountPolicyException
  • PasswordPolicyException
  • PolicyEnforceException
  • UnauthorizedRoleException
  • PropagationException
  • ReportException
  • WorkflowException
  • No labels