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 |   47 +++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 39 insertions(+), 8 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 9fa35c5..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,19 +24,19 @@
     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,
                                     Long firstTokenAt, AiChatException exception, Long callLogId,
                                     long toolSuccessCount, long toolFailureCount,
-                                    AiThinkingTraceEmitter thinkingTraceEmitter,
+                                    AiChatTraceEmitter traceEmitter,
                                     Long tenantId, Long userId, String promptCode) {
         if (isClientAbortException(exception)) {
             log.warn("AI chat aborted by client, requestId={}, sessionId={}, stage={}, message={}",
                     requestId, sessionId, exception.getStage(), exception.getMessage());
-            if (thinkingTraceEmitter != null) {
-                thinkingTraceEmitter.markTerminated("ABORTED");
+            if (traceEmitter != null) {
+                traceEmitter.markTerminated("ABORTED");
             }
             aiSseEventPublisher.emitSafely(emitter, "status",
                     aiSseEventPublisher.buildTerminalStatus(requestId, sessionId, "ABORTED", model, startedAt, firstTokenAt));
@@ -50,13 +52,13 @@
                     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={}",
                 requestId, sessionId, exception.getCategory(), exception.getStage(), exception.getMessage(), exception);
-        if (thinkingTraceEmitter != null) {
-            thinkingTraceEmitter.markTerminated("FAILED");
+        if (traceEmitter != null) {
+            traceEmitter.markTerminated("FAILED");
         }
         aiSseEventPublisher.emitSafely(emitter, "status",
                 aiSseEventPublisher.buildTerminalStatus(requestId, sessionId, "FAILED", model, startedAt, firstTokenAt));
@@ -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