Background
GlobalExceptionHandler (src/main/java/br/com/arquivolivre/myjavagenie/controller/GlobalExceptionHandler.java) returns ex.getMessage() verbatim to clients for IllegalArgumentException, ModelTimeoutException, ModelInvocationException, ModelInitializationException, and the generic handler. These messages are built from provider/exception internals, e.g. "Language model generation failed: " + e.getMessage() in QueryService.generateWithTimeout, which can embed upstream API error details.
Impact
- Internal details (base URLs, request fragments, provider error payloads, filesystem paths) can leak to API consumers and the chat UI.
- Error handling is inconsistent: some paths sanitize via
LogSanitizer, but the client-facing body does not.
- The chat UI surfaces these messages directly in the error banner, so a user can see provider internals.
How to reproduce
- Point
model.self-hosted.base-url at a closed port (or use an invalid API key).
- Ask a question via
POST /api/chat/query.
- Observe the response body contains the raw connection/authentication error message from the provider instead of a generic message.
Where the fix should land
In GlobalExceptionHandler, map each exception type to a stable, user-facing message while keeping the current HTTP statuses:
- Timeout → "The request timed out while generating the answer. Please try again."
- Invocation/initialization → "The language model is temporarily unavailable. Please try again later."
- Generic → "An unexpected error occurred."
Keep full detail in the logs (the handlers already log with the exception object).
Files touched
src/main/java/br/com/arquivolivre/myjavagenie/controller/GlobalExceptionHandler.java
- Tests under
src/test/java/... (new GlobalExceptionHandlerTest or updates to existing controller tests)
Acceptance criteria
Background
GlobalExceptionHandler(src/main/java/br/com/arquivolivre/myjavagenie/controller/GlobalExceptionHandler.java) returnsex.getMessage()verbatim to clients forIllegalArgumentException,ModelTimeoutException,ModelInvocationException,ModelInitializationException, and the generic handler. These messages are built from provider/exception internals, e.g."Language model generation failed: " + e.getMessage()inQueryService.generateWithTimeout, which can embed upstream API error details.Impact
LogSanitizer, but the client-facing body does not.How to reproduce
model.self-hosted.base-urlat a closed port (or use an invalid API key).POST /api/chat/query.Where the fix should land
In
GlobalExceptionHandler, map each exception type to a stable, user-facing message while keeping the current HTTP statuses:Keep full detail in the logs (the handlers already log with the exception object).
Files touched
src/main/java/br/com/arquivolivre/myjavagenie/controller/GlobalExceptionHandler.javasrc/test/java/...(newGlobalExceptionHandlerTestor updates to existing controller tests)Acceptance criteria
mvn testandmvn spotless:checkpass.