From ca13eca7bdf329e283fb4d6ce8188da8651d86ed Mon Sep 17 00:00:00 2001
From: Zane <75694352+zanesq@users.noreply.github.com>
Date: Thu, 17 Jul 2025 15:33:44 -0700
Subject: [PATCH] Fix llm errors not propagating to the ui and auto summarize
not starting (#3490)
---
ui/desktop/src/components/BaseChat.tsx | 77 +++++++++++++++++-------
ui/desktop/src/hooks/useChatEngine.ts | 17 ++++++
ui/desktop/src/hooks/useMessageStream.ts | 50 ++++++++++++++-
3 files changed, 118 insertions(+), 26 deletions(-)
diff --git a/ui/desktop/src/components/BaseChat.tsx b/ui/desktop/src/components/BaseChat.tsx
index f26ab7c0..247d8bee 100644
--- a/ui/desktop/src/components/BaseChat.tsx
+++ b/ui/desktop/src/components/BaseChat.tsx
@@ -237,7 +237,6 @@ function BaseChatContent({
});
useEffect(() => {
- // Log all messages when the component first mounts
window.electron.logInfo(
'Initial messages when resuming session: ' + JSON.stringify(chat.messages, null, 2)
);
@@ -414,28 +413,60 @@ function BaseChatContent({
)}
- {error && (
-
-
- {error.message || 'Honk! Goose experienced an error while responding'}
-
-
{
- // Find the last user message
- const lastUserMessage = messages.reduceRight(
- (found, m) => found || (m.role === 'user' ? m : null),
- null as Message | null
- );
- if (lastUserMessage) {
- append(lastUserMessage);
- }
- }}
- >
- Retry Last Message
-
-
- )}
+ {error &&
+ !(error as Error & { isTokenLimitError?: boolean }).isTokenLimitError && (
+ <>
+
+
+ {error.message || 'Honk! Goose experienced an error while responding'}
+
+
+ {/* Expandable Error Details */}
+
+
+ Error details
+
+
+
+ Error Type: {error.name || 'Unknown'}
+
+
+ Message: {error.message || 'No message'}
+
+ {error.stack && (
+
+
Stack Trace:
+
+ {error.stack}
+
+
+ )}
+
+
+
+ {/* Regular retry button for non-token-limit errors */}
+
{
+ // Find the last user message
+ const lastUserMessage = messages.reduceRight(
+ (found, m) => found || (m.role === 'user' ? m : null),
+ null as Message | null
+ );
+ if (lastUserMessage) {
+ append(lastUserMessage);
+ }
+ }}
+ >
+ Retry Last Message
+
+
+ >
+ )}
+
+ {/* Token limit errors should be handled by ContextHandler, not shown here */}
+ {error &&
+ (error as Error & { isTokenLimitError?: boolean }).isTokenLimitError && <>>}
>
) : showPopularTopics ? (
diff --git a/ui/desktop/src/hooks/useChatEngine.ts b/ui/desktop/src/hooks/useChatEngine.ts
index 857f99e6..c852b169 100644
--- a/ui/desktop/src/hooks/useChatEngine.ts
+++ b/ui/desktop/src/hooks/useChatEngine.ts
@@ -108,6 +108,23 @@ export const useChatEngine = ({
onMessageStreamFinish?.();
},
+ onError: (error) => {
+ console.log(
+ 'CHAT ENGINE RECEIVED ERROR FROM MESSAGE STREAM:',
+ JSON.stringify(
+ {
+ errorMessage: error.message,
+ errorName: error.name,
+ isTokenLimitError: (error as Error & { isTokenLimitError?: boolean }).isTokenLimitError,
+ errorStack: error.stack,
+ timestamp: new Date().toISOString(),
+ chatId: chat.id,
+ },
+ null,
+ 2
+ )
+ );
+ },
});
// Wrap append to store messages in global history (if enabled)
diff --git a/ui/desktop/src/hooks/useMessageStream.ts b/ui/desktop/src/hooks/useMessageStream.ts
index 4277b16a..1f300f0c 100644
--- a/ui/desktop/src/hooks/useMessageStream.ts
+++ b/ui/desktop/src/hooks/useMessageStream.ts
@@ -323,8 +323,45 @@ export function useMessageStream({
break;
}
- case 'Error':
- throw new Error(parsedEvent.error);
+ case 'Error': {
+ // Check if this is a token limit error (more specific detection)
+ const errorMessage = parsedEvent.error;
+ const isTokenLimitError =
+ errorMessage &&
+ ((errorMessage.toLowerCase().includes('token') &&
+ errorMessage.toLowerCase().includes('limit')) ||
+ (errorMessage.toLowerCase().includes('context') &&
+ errorMessage.toLowerCase().includes('length') &&
+ errorMessage.toLowerCase().includes('exceeded')));
+
+ // If this is a token limit error, create a contextLengthExceeded message instead of throwing
+ if (isTokenLimitError) {
+ const contextMessage: Message = {
+ id: `context-${Date.now()}`,
+ role: 'assistant',
+ created: Math.floor(Date.now() / 1000),
+ content: [
+ {
+ type: 'contextLengthExceeded',
+ msg: errorMessage,
+ },
+ ],
+ display: true,
+ sendToLLM: false,
+ };
+
+ currentMessages = [...currentMessages, contextMessage];
+ mutate(currentMessages, false);
+
+ // Clear any existing error state since we handled this as a context message
+ setError(undefined);
+ break; // Don't throw error, just add the message
+ }
+
+ // For non-token-limit errors, still throw the error
+ const error = new Error(parsedEvent.error);
+ throw error;
+ }
case 'Finish': {
// Call onFinish with the last message if available
@@ -371,6 +408,11 @@ export function useMessageStream({
if (onError && e instanceof Error) {
onError(e);
}
+ // Don't re-throw here, let the error be handled by the outer catch
+ // Instead, set the error state directly
+ if (e instanceof Error) {
+ setError(e);
+ }
}
}
}
@@ -381,6 +423,8 @@ export function useMessageStream({
if (onError) {
onError(e);
}
+ // Re-throw the error so it gets caught by sendRequest and sets the error state
+ throw e;
}
} finally {
reader.releaseLock();
@@ -388,7 +432,7 @@ export function useMessageStream({
return currentMessages;
},
- [mutate, onFinish, onError, forceUpdate]
+ [mutate, onFinish, onError, forceUpdate, setError]
);
// Send a request to the server