From 66d766c88ec5d1ab4715fd9f2c22ce42b459d957 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期四, 02 四月 2026 18:32:20 +0800
Subject: [PATCH] #

---
 rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/chat/AiChatFailureHandler.java |   37 ++++++++++++++++++++++++++++++++++---
 1 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/chat/AiChatFailureHandler.java b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/chat/AiChatFailureHandler.java
index d9f9d91..133aa27 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/chat/AiChatFailureHandler.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/ai/service/impl/chat/AiChatFailureHandler.java
@@ -8,6 +8,8 @@
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
 import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
 import java.time.Instant;
@@ -22,7 +24,7 @@
     private final AiStreamStateStore aiStreamStateStore;
 
     public AiChatException buildAiException(String code, AiErrorCategory category, String stage, String message, Throwable cause) {
-        return new AiChatException(code, category, stage, message, cause);
+        return new AiChatException(code, category, stage, resolveExceptionMessage(message, cause), cause);
     }
 
     public void handleStreamFailure(SseEmitter emitter, String requestId, Long sessionId, String model, long startedAt,
@@ -50,7 +52,7 @@
                     toolFailureCount
             );
             aiStreamStateStore.markStreamState(requestId, tenantId, userId, sessionId, promptCode, "ABORTED", exception.getMessage());
-            emitter.completeWithError(exception);
+            emitter.complete();
             return;
         }
         log.error("AI chat failed, requestId={}, sessionId={}, category={}, stage={}, message={}",
@@ -81,7 +83,36 @@
                 toolFailureCount
         );
         aiStreamStateStore.markStreamState(requestId, tenantId, userId, sessionId, promptCode, "FAILED", exception.getMessage());
-        emitter.completeWithError(exception);
+        emitter.complete();
+    }
+
+    private String resolveExceptionMessage(String message, Throwable cause) {
+        String upstreamMessage = extractUpstreamResponseBody(cause);
+        if (StringUtils.hasText(upstreamMessage)) {
+            return truncateMessage(upstreamMessage);
+        }
+        return truncateMessage(message);
+    }
+
+    private String extractUpstreamResponseBody(Throwable throwable) {
+        Throwable current = throwable;
+        while (current != null) {
+            if (current instanceof WebClientResponseException webClientResponseException) {
+                String responseBody = webClientResponseException.getResponseBodyAsString();
+                if (StringUtils.hasText(responseBody)) {
+                    return responseBody.replace('\n', ' ').replace('\r', ' ').trim();
+                }
+            }
+            current = current.getCause();
+        }
+        return null;
+    }
+
+    private String truncateMessage(String message) {
+        if (!StringUtils.hasText(message)) {
+            return message;
+        }
+        return message.length() > 900 ? message.substring(0, 900) : message;
     }
 
     private boolean isClientAbortException(Throwable throwable) {

--
Gitblit v1.9.1