fix(desktop): prevent transformCallback crash in browser mode
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

Root cause: ChatArea.tsx called listen() from @tauri-apps/api/event
directly on component mount without checking isTauriRuntime(). When
accessed from a regular browser (not Tauri WebView), window.__TAURI_INTERNALS__
is undefined, causing "Cannot read properties of undefined (reading 'transformCallback')".

Solution:
- Created lib/safe-tauri.ts with safe wrappers (safeInvoke, safeListen,
  safeListenEvent, requireInvoke) that gracefully degrade when Tauri
  IPC is unavailable
- Replaced direct listen() call in ChatArea.tsx with safeListenEvent()
This commit is contained in:
iven
2026-04-03 13:00:36 +08:00
parent 564c7ca28f
commit 5b1b747810
2 changed files with 107 additions and 2 deletions

View File

@@ -7,7 +7,8 @@ import { useArtifactStore } from '../store/chat/artifactStore';
import { useConnectionStore } from '../store/connectionStore';
import { useAgentStore } from '../store/agentStore';
import { useConfigStore } from '../store/configStore';
import { listen, type UnlistenFn } from '@tauri-apps/api/event';
import { type UnlistenFn } from '@tauri-apps/api/event';
import { safeListenEvent } from '../lib/safe-tauri';
import { Paperclip, SquarePen, ArrowUp, MessageSquare, Download, X, FileText, Image as ImageIcon } from 'lucide-react';
import { Button, EmptyState, MessageListSkeleton, LoadingDots } from './ui';
import { ResizableChatLayout } from './ai/ResizableChatLayout';
@@ -160,7 +161,7 @@ export function ChatArea() {
// Listen for hand-execution-complete Tauri events
useEffect(() => {
let unlisten: UnlistenFn | undefined;
listen<{ approvalId: string; handId: string; success: boolean; error?: string | null }>(
safeListenEvent<{ approvalId: string; handId: string; success: boolean; error?: string | null }>(
'hand-execution-complete',
(event) => {
const { handId, success, error } = event.payload;