feat(chat): add localized error message for model API call and improve error handling in chat history (#947)
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"runError": {
|
||||
"title": "Model API call error"
|
||||
},
|
||||
"gatewayNotRunning": "Gateway Not Running",
|
||||
"gatewayRequired": "The OpenClaw Gateway needs to be running to use chat. It will start automatically, or you can start it from Settings.",
|
||||
"welcome": {
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"runError": {
|
||||
"title": "モデルAPI呼び出しエラー"
|
||||
},
|
||||
"gatewayNotRunning": "ゲートウェイが停止中",
|
||||
"gatewayRequired": "チャットを利用するには OpenClaw ゲートウェイが実行されている必要があります。自動的に起動するか、設定から起動できます。",
|
||||
"welcome": {
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"runError": {
|
||||
"title": "Ошибка вызова API модели"
|
||||
},
|
||||
"gatewayNotRunning": "Шлюз не запущен",
|
||||
"gatewayRequired": "Для использования чата требуется запущенный шлюз OpenClaw. Он запустится автоматически, или вы можете запустить его в Настройках.",
|
||||
"welcome": {
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"runError": {
|
||||
"title": "模型API调用错误"
|
||||
},
|
||||
"gatewayNotRunning": "网关未运行",
|
||||
"gatewayRequired": "OpenClaw 网关需要运行才能使用聊天。它将自动启动,或者您可以从设置中启动。",
|
||||
"welcome": {
|
||||
|
||||
@@ -805,7 +805,7 @@ export function Chat() {
|
||||
|
||||
{/* Run error callout */}
|
||||
{runError && (
|
||||
<div className="px-4 pt-2">
|
||||
<div className="px-4 pt-2" data-testid="chat-run-error">
|
||||
<div className="max-w-4xl mx-auto rounded-xl border border-destructive/20 bg-destructive/10 px-4 py-3">
|
||||
<p className="text-sm font-medium text-destructive flex items-center gap-2">
|
||||
<AlertCircle className="h-4 w-4" />
|
||||
|
||||
@@ -416,6 +416,9 @@ test.describe('ClawX chat execution graph', () => {
|
||||
|
||||
await expect(page.getByTestId('main-layout')).toBeVisible();
|
||||
await expect(page.getByText('404 Resource not found')).toBeVisible({ timeout: 30_000 });
|
||||
const runErrorCallout = page.getByTestId('chat-run-error');
|
||||
await expect(runErrorCallout).toBeVisible({ timeout: 30_000 });
|
||||
await expect(runErrorCallout).toContainText('404 Resource not found');
|
||||
await expect(page.getByTestId('chat-execution-graph')).toHaveCount(0);
|
||||
await expect(page.getByTestId('chat-execution-step-thinking-trailing')).toHaveCount(0);
|
||||
await expect(page.getByText('404 Resource not found')).toHaveCount(1);
|
||||
|
||||
@@ -308,6 +308,37 @@ describe('chat history actions', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('does not set runError from an older assistant failure when a later turn succeeded', async () => {
|
||||
const { createHistoryActions } = await import('@/stores/chat/history-actions');
|
||||
const h = makeHarness({
|
||||
currentSessionKey: 'agent:main:main',
|
||||
runError: 'stale',
|
||||
});
|
||||
const actions = createHistoryActions(h.set as never, h.get as never);
|
||||
|
||||
invokeIpcMock.mockResolvedValueOnce({
|
||||
success: true,
|
||||
result: {
|
||||
messages: [
|
||||
{ role: 'user', content: 'first', timestamp: 1773281730 },
|
||||
{
|
||||
role: 'assistant',
|
||||
content: 'fail',
|
||||
timestamp: 1773281731,
|
||||
stopReason: 'error',
|
||||
errorMessage: '400 bad model',
|
||||
},
|
||||
{ role: 'user', content: 'retry', timestamp: 1773281732 },
|
||||
{ role: 'assistant', content: 'ok now', timestamp: 1773281733 },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
await actions.loadHistory(true);
|
||||
|
||||
expect(h.read().runError).toBeNull();
|
||||
});
|
||||
|
||||
it('retries the first foreground startup history load after a timeout and then succeeds', async () => {
|
||||
vi.useFakeTimers();
|
||||
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
||||
|
||||
Reference in New Issue
Block a user