Fix llm errors not propagating to the ui and auto summarize not starting (#3490)
This commit is contained in:
@@ -237,7 +237,6 @@ function BaseChatContent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Log all messages when the component first mounts
|
|
||||||
window.electron.logInfo(
|
window.electron.logInfo(
|
||||||
'Initial messages when resuming session: ' + JSON.stringify(chat.messages, null, 2)
|
'Initial messages when resuming session: ' + JSON.stringify(chat.messages, null, 2)
|
||||||
);
|
);
|
||||||
@@ -414,28 +413,60 @@ function BaseChatContent({
|
|||||||
</SearchView>
|
</SearchView>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{error && (
|
{error &&
|
||||||
<div className="flex flex-col items-center justify-center p-4">
|
!(error as Error & { isTokenLimitError?: boolean }).isTokenLimitError && (
|
||||||
<div className="text-red-700 dark:text-red-300 bg-red-400/50 p-3 rounded-lg mb-2">
|
<>
|
||||||
{error.message || 'Honk! Goose experienced an error while responding'}
|
<div className="flex flex-col items-center justify-center p-4">
|
||||||
</div>
|
<div className="text-red-700 dark:text-red-300 bg-red-400/50 p-3 rounded-lg mb-2">
|
||||||
<div
|
{error.message || 'Honk! Goose experienced an error while responding'}
|
||||||
className="px-3 py-2 mt-2 text-center whitespace-nowrap cursor-pointer text-textStandard border border-borderSubtle hover:bg-bgSubtle rounded-full inline-block transition-all duration-150"
|
</div>
|
||||||
onClick={async () => {
|
|
||||||
// Find the last user message
|
{/* Expandable Error Details */}
|
||||||
const lastUserMessage = messages.reduceRight(
|
<details className="w-full max-w-2xl mb-2">
|
||||||
(found, m) => found || (m.role === 'user' ? m : null),
|
<summary className="text-xs text-textSubtle cursor-pointer hover:text-textStandard transition-colors">
|
||||||
null as Message | null
|
Error details
|
||||||
);
|
</summary>
|
||||||
if (lastUserMessage) {
|
<div className="mt-2 p-3 bg-bgSubtle border border-borderSubtle rounded-lg text-xs font-mono text-textStandard">
|
||||||
append(lastUserMessage);
|
<div className="mb-2">
|
||||||
}
|
<strong>Error Type:</strong> {error.name || 'Unknown'}
|
||||||
}}
|
</div>
|
||||||
>
|
<div className="mb-2">
|
||||||
Retry Last Message
|
<strong>Message:</strong> {error.message || 'No message'}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{error.stack && (
|
||||||
)}
|
<div>
|
||||||
|
<strong>Stack Trace:</strong>
|
||||||
|
<pre className="mt-1 whitespace-pre-wrap text-xs overflow-x-auto">
|
||||||
|
{error.stack}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
{/* Regular retry button for non-token-limit errors */}
|
||||||
|
<div
|
||||||
|
className="px-3 py-2 mt-2 text-center whitespace-nowrap cursor-pointer text-textStandard border border-borderSubtle hover:bg-bgSubtle rounded-full inline-block transition-all duration-150"
|
||||||
|
onClick={async () => {
|
||||||
|
// 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
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Token limit errors should be handled by ContextHandler, not shown here */}
|
||||||
|
{error &&
|
||||||
|
(error as Error & { isTokenLimitError?: boolean }).isTokenLimitError && <></>}
|
||||||
<div className="block h-8" />
|
<div className="block h-8" />
|
||||||
</>
|
</>
|
||||||
) : showPopularTopics ? (
|
) : showPopularTopics ? (
|
||||||
|
|||||||
@@ -108,6 +108,23 @@ export const useChatEngine = ({
|
|||||||
|
|
||||||
onMessageStreamFinish?.();
|
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)
|
// Wrap append to store messages in global history (if enabled)
|
||||||
|
|||||||
@@ -323,8 +323,45 @@ export function useMessageStream({
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'Error':
|
case 'Error': {
|
||||||
throw new Error(parsedEvent.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': {
|
case 'Finish': {
|
||||||
// Call onFinish with the last message if available
|
// Call onFinish with the last message if available
|
||||||
@@ -371,6 +408,11 @@ export function useMessageStream({
|
|||||||
if (onError && e instanceof Error) {
|
if (onError && e instanceof Error) {
|
||||||
onError(e);
|
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) {
|
if (onError) {
|
||||||
onError(e);
|
onError(e);
|
||||||
}
|
}
|
||||||
|
// Re-throw the error so it gets caught by sendRequest and sets the error state
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
reader.releaseLock();
|
reader.releaseLock();
|
||||||
@@ -388,7 +432,7 @@ export function useMessageStream({
|
|||||||
|
|
||||||
return currentMessages;
|
return currentMessages;
|
||||||
},
|
},
|
||||||
[mutate, onFinish, onError, forceUpdate]
|
[mutate, onFinish, onError, forceUpdate, setError]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send a request to the server
|
// Send a request to the server
|
||||||
|
|||||||
Reference in New Issue
Block a user