Skip to content

Commit 87bf4fa

Browse files
authored
🐛 The conversation will be stopped and the reason will be prompted when uploaded too large files #1246 #1247
2 parents 3fb447c + 90fb8c3 commit 87bf4fa

File tree

6 files changed

+69
-17
lines changed

6 files changed

+69
-17
lines changed

frontend/app/[locale]/chat/internal/chatInterface.tsx

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ export function ChatInterface() {
250250
const handleSend = async () => {
251251
if (!input.trim() && attachments.length === 0) return; // Allow sending attachments only, without text content
252252

253+
// Flag to track if we should reset button states in finally block
254+
let shouldResetButtonStates = true;
255+
253256
// If in new conversation state, switch to conversation state after sending message
254257
if (isNewConversation) {
255258
setIsNewConversation(false);
@@ -373,6 +376,10 @@ export function ChatInterface() {
373376
t("chatInterface.createDialogFailedButContinue"),
374377
error
375378
);
379+
// Reset button states when conversation creation fails
380+
setIsLoading(false);
381+
setIsStreaming(false);
382+
return;
376383
}
377384
}
378385

@@ -594,20 +601,47 @@ export function ChatInterface() {
594601

595602
// Handle preprocessing result
596603
if (!result.success) {
604+
// Reset button states immediately when preprocessing fails
605+
setIsLoading(false);
606+
setIsStreaming(false);
607+
608+
// Remove from streaming conversations (both new and existing conversations)
609+
if (currentConversationId) {
610+
setStreamingConversations((prev) => {
611+
const newSet = new Set(prev);
612+
newSet.delete(currentConversationId);
613+
return newSet;
614+
});
615+
}
616+
597617
setSessionMessages((prev) => {
598618
const newMessages = { ...prev };
599619
const lastMsg =
600620
newMessages[currentConversationId]?.[
601621
newMessages[currentConversationId].length - 1
602622
];
623+
603624
if (lastMsg && lastMsg.role === ROLE_ASSISTANT) {
604-
lastMsg.error = t("chatInterface.fileProcessingFailed", {
605-
error: result.error,
606-
});
625+
// Handle error codes with internationalization
626+
let errorMessage;
627+
if (result.error === 'REQUEST_ENTITY_TOO_LARGE') {
628+
errorMessage = t("chatInterface.fileSizeExceeded");
629+
} else if (result.error === 'FILE_PARSING_FAILED') {
630+
errorMessage = t("chatInterface.fileParsingFailed");
631+
} else {
632+
// For any other error, show a generic message without exposing technical details
633+
errorMessage = t("chatInterface.fileProcessingFailed", {
634+
error: "Unknown error"
635+
});
636+
}
637+
638+
lastMsg.content = errorMessage;
607639
lastMsg.isComplete = true;
608640
}
641+
609642
return newMessages;
610643
});
644+
shouldResetButtonStates = false; // Don't reset again in finally block
611645
return;
612646
}
613647

@@ -810,10 +844,8 @@ export function ChatInterface() {
810844
});
811845
} else {
812846
log.error(t("chatInterface.errorLabel"), error);
813-
const errorMessage =
814-
error instanceof Error
815-
? error.message
816-
: t("chatInterface.errorProcessingRequest");
847+
// Show user-friendly error message instead of technical error details
848+
const errorMessage = t("chatInterface.errorProcessingRequest");
817849
setSessionMessages((prev) => {
818850
const newMessages = { ...prev };
819851
const lastMsg =
@@ -862,6 +894,12 @@ export function ChatInterface() {
862894
});
863895
}
864896
}
897+
} finally {
898+
// Only reset button states if we should (not when preprocessing fails)
899+
if (shouldResetButtonStates) {
900+
setIsLoading(false);
901+
setIsStreaming(false);
902+
}
865903
}
866904
};
867905

@@ -1085,10 +1123,7 @@ export function ChatInterface() {
10851123

10861124
setConversationLoadError((prev) => ({
10871125
...prev,
1088-
[dialog.conversation_id]:
1089-
error instanceof Error
1090-
? error.message
1091-
: "Failed to load conversation",
1126+
[dialog.conversation_id]: "Failed to load conversation",
10921127
}));
10931128
} finally {
10941129
// ensure loading state is cleared
@@ -1228,10 +1263,7 @@ export function ChatInterface() {
12281263

12291264
setConversationLoadError((prev) => ({
12301265
...prev,
1231-
[dialog.conversation_id]:
1232-
error instanceof Error
1233-
? error.message
1234-
: "Failed to load conversation",
1266+
[dialog.conversation_id]: "Failed to load conversation",
12351267
}));
12361268
} finally {
12371269
// ensure loading state is cleared

frontend/const/auth.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export const STATUS_CODES = {
33
SUCCESS: 200,
44

55
UNAUTHORIZED_HTTP: 401,
6+
REQUEST_ENTITY_TOO_LARGE: 413,
67

78
INVALID_CREDENTIALS: 1002,
89
TOKEN_EXPIRED: 1003,

frontend/public/locales/en/common.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
"chatInterface.fileParsingCompleteWithTruncation": "File parsing complete: {{truncationInfo}}",
3030
"chatInterface.truncationSeparator": "; ",
3131
"chatInterface.fileProcessingFailed": "File processing failed: {{error}}",
32+
"chatInterface.fileParsingFailed": "File parsing failed",
33+
"chatInterface.fileSizeExceeded": "File size exceeds the limit, please upload smaller files",
3234
"chatInterface.filePreprocessingStopped": "File parsing stopped",
3335
"chatInterface.userCancelledRequest": "User canceled the request",
3436
"chatInterface.conversationStopped": "Conversation stopped",

frontend/public/locales/zh/common.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
"chatInterface.fileParsingCompleteWithTruncation": "文件解析完成:{{truncationInfo}}",
3030
"chatInterface.truncationSeparator": "",
3131
"chatInterface.fileProcessingFailed": "文件处理失败: {{error}}",
32+
"chatInterface.fileParsingFailed": "文件解析失败",
33+
"chatInterface.fileSizeExceeded": "文件大小超出限制,请上传更小的文件",
3234
"chatInterface.filePreprocessingStopped": "文件解析已停止",
3335
"chatInterface.userCancelledRequest": "用户取消了请求",
3436
"chatInterface.conversationStopped": "对话已停止",

frontend/services/api.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ export const fetchWithErrorHandling = async (url: string, options: RequestInit =
181181
throw new ApiError(STATUS_CODES.TOKEN_EXPIRED, "Connection disconnected, session may have expired");
182182
}
183183

184+
// Handle request entity too large error (413)
185+
if (response.status === 413) {
186+
throw new ApiError(STATUS_CODES.REQUEST_ENTITY_TOO_LARGE, "REQUEST_ENTITY_TOO_LARGE");
187+
}
188+
184189
// Other HTTP errors
185190
const errorText = await response.text();
186191
throw new ApiError(response.status, errorText || `Request failed: ${response.status}`);

frontend/services/conversationService.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,17 @@ export const conversationService = {
705705
signal,
706706
});
707707

708+
// Check if the response is successful
709+
if (!response.ok) {
710+
// Handle specific HTTP status codes with error codes for internationalization
711+
if (response.status === 413) {
712+
throw new Error('REQUEST_ENTITY_TOO_LARGE');
713+
} else {
714+
throw new Error('FILE_PARSING_FAILED');
715+
716+
}
717+
}
718+
708719
if (!response.body) {
709720
throw new Error("Response body is null");
710721
}
@@ -713,8 +724,7 @@ export const conversationService = {
713724
} catch (error) {
714725
// If the error is caused by canceling the request, return a specific response instead of throwing an error
715726
if (error instanceof Error && error.name === 'AbortError') {
716-
log.log('文件预处理请求已被取消');
717-
throw new Error('请求已被取消');
727+
throw new Error('Request has been aborted');
718728
}
719729
// Other errors are thrown normally
720730
throw error;

0 commit comments

Comments
 (0)