Error Handling

Error Contract

Errors are returned as ErrorDetails from dependency com.friendly:ft-exceptions and produced by GlobalExceptionHandler (src/main/java/com/friendly/ftconfigsservice/utils/exception/GlobalExceptionHandler.java).

Shape (example):

{
  "message": "Localized message to show to user",
  "description": "Additional technical description",
  "code": 123
}

HTTP status is derived from the error code inside ErrorDetails.

Localization

GlobalExceptionHandler#createErrorResponse localizes messages using:

  • service_errors*.properties (MessageSourceConfig#errorsMessageSource)

  • Locale resolved from the current principal via AuthUtils.getUserLocale()

Dry-run specific messages use separate bundle dry_run_messages*.properties via bean dryRunMessageSource.

Exception Classification (as implemented)

Handled explicitly:

  • FriendlyException → returned as-is (localized when possible)

  • ConstraintViolationException → mapped to ConfigsErrorCode.VALIDATION_ERROR with joined violations

  • DataIntegrityViolationException / SQLIntegrityConstraintViolationException → mapped to FriendlyErrorCode.DATA_INTEGRITY_ERROR

  • Client disconnects (ClientAbortException, certain IOException) → mapped to FriendlyErrorCode.CLIENT_CONNECTION_CLOSED

  • All other Throwable → mapped to FriendlyErrorCode.INTERNAL_ERROR

Troubleshooting Notes

  • Missing Authorization header triggers FriendlyErrorCode.UNAUTHORIZED (special-cased in handleMissingRequestHeaderException).

  • Request bodies are logged when ContentCachingRequestWrapper is used by the servlet container; otherwise logs will show “No request body available.”