From bc564c5c8c94698b2cfa9d30aa6462b810892907 Mon Sep 17 00:00:00 2001 From: PAVEL PALMA Date: Thu, 29 Jan 2026 10:52:06 -0600 Subject: [PATCH] UPDATE Jueves 29 de Enero --- .../service/base/DialogflowClientService.java | 41 +++++++++++++++++-- .../ConversationManagerService.java | 2 +- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/example/service/base/DialogflowClientService.java b/src/main/java/com/example/service/base/DialogflowClientService.java index 9d13567..5c90f8c 100644 --- a/src/main/java/com/example/service/base/DialogflowClientService.java +++ b/src/main/java/com/example/service/base/DialogflowClientService.java @@ -23,6 +23,7 @@ import reactor.core.publisher.Mono; import javax.annotation.PreDestroy; import java.io.IOException; import java.util.Objects; +import reactor.util.retry.Retry; /** * Service for interacting with the Dialogflow CX API to detect user DetectIntent. @@ -118,16 +119,48 @@ public class DialogflowClientService { // Build the final DetectIntentRequest Protobuf object DetectIntentRequest detectIntentRequest = detectIntentRequestBuilder.build(); - logger.debug("DetectIntentRequest created for session {}: {}", sessionId, detectIntentRequest); return Mono.fromCallable(() -> { logger.debug("Calling Dialogflow CX detectIntent for session: {}", sessionId); return sessionsClient.detectIntent(detectIntentRequest); }) + + .retryWhen(reactor.util.retry.Retry.backoff(3, java.time.Duration.ofSeconds(1)) + .filter(throwable -> { + if (throwable instanceof ApiException apiException) { + com.google.api.gax.rpc.StatusCode.Code code = apiException.getStatusCode().getCode(); + boolean isRetryable = code == com.google.api.gax.rpc.StatusCode.Code.INTERNAL || + code == com.google.api.gax.rpc.StatusCode.Code.UNAVAILABLE; + if (isRetryable) { + logger.warn("Retrying Dialogflow CX call for session {} due to transient error: {}", sessionId, code); + } + return isRetryable; + } + return false; + }) + .doBeforeRetry(retrySignal -> logger.debug("Retry attempt #{} for session {}", + retrySignal.totalRetries() + 1, sessionId)) + .onRetryExhaustedThrow((retrySpec, retrySignal) -> { + logger.error("Dialogflow CX retries exhausted for session {}", sessionId); + return retrySignal.failure(); + }) + ) .onErrorMap(ApiException.class, e -> { - logger.error("Dialogflow CX API error for session {}: status={}, message={}", - sessionId, e.getStatusCode().getCode(), e.getMessage(), e); + String statusCode = e.getStatusCode().getCode().name(); + String message = e.getMessage(); + String detailedLog = message; + + if (e.getCause() instanceof io.grpc.StatusRuntimeException grpcEx) { + detailedLog = String.format("Status: %s, Message: %s, Trailers: %s", + grpcEx.getStatus().getCode(), + grpcEx.getStatus().getDescription(), + grpcEx.getTrailers()); + } + + logger.error("Dialogflow CX API error for session {}: details={}", + sessionId, detailedLog, e); + return new DialogflowClientException( - "Dialogflow CX API error: " + e.getStatusCode().getCode() + " - " + e.getMessage(), e); + "Dialogflow CX API error: " + statusCode + " - " + message, e); }) .map(dfResponse -> this.dialogflowResponseMapper.mapFromDialogflowResponse(dfResponse, sessionId)); } diff --git a/src/main/java/com/example/service/conversation/ConversationManagerService.java b/src/main/java/com/example/service/conversation/ConversationManagerService.java index 1de7df9..148c299 100644 --- a/src/main/java/com/example/service/conversation/ConversationManagerService.java +++ b/src/main/java/com/example/service/conversation/ConversationManagerService.java @@ -308,7 +308,7 @@ public class ConversationManagerService { .then(Mono.defer(() -> dialogflowServiceClient.detectIntent(finalSessionId, request) .flatMap(response -> { logger.debug( - "Received Dialogflow CX response for session {}. Initiating agent response persistence.", + "RTest eceived Dialogflow CX response for session {}. Initiating agent response persistence.", finalSessionId); ConversationEntryDTO agentEntry = ConversationEntryDTO.forAgent(response.queryResult()); return persistConversationTurn(session, conversationEntryMapper.toConversationMessageDTO(agentEntry))