{"record":{"id":"f0363fee02b4e64c","repo":"jlcodes99/cockpit-tools","slug":"workbuddyautocheckin-f0363f","errorCode":null,"errorMessage":"[WorkbuddyAutoCheckin] 监听后端签到配置事件失败:","messagePattern":"\\[WorkbuddyAutoCheckin\\] 监听后端签到配置事件失败:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/components/codebuddy-suite/CodebuddySuiteCheckinModal.tsx","lineNumber":127,"sourceCode":"    const handleConfigChange = () => {\n      void getWorkbuddyAutoCheckinConfigAsync().then((nextConfig) => {\n        if (!disposed) {\n          setAutoCheckinConfig(nextConfig);\n        }\n      });\n    };\n    handleConfigChange();\n    window.addEventListener(WORKBUDDY_AUTO_CHECKIN_CONFIG_CHANGED_EVENT, handleConfigChange);\n    void listen(WORKBUDDY_AUTO_CHECKIN_CONFIG_CHANGED_EVENT, handleConfigChange)\n      .then((stopListening) => {\n        if (disposed) {\n          stopListening();\n        } else {\n          unlisten = stopListening;\n        }\n      })\n      .catch((err) => {\n        console.warn('[WorkbuddyAutoCheckin] 监听后端签到配置事件失败:', err);\n      });\n    return () => {\n      disposed = true;\n      unlisten?.();\n      window.removeEventListener(WORKBUDDY_AUTO_CHECKIN_CONFIG_CHANGED_EVENT, handleConfigChange);\n    };\n  }, []);\n\n  useEffect(() => {\n    if (accounts.length > 0) {\n      void fetchAllStatus();\n    }\n  }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n  const updateAccountState = useCallback(\n    (accountId: string, patch: Partial<AccountCheckinState>) => {\n      setAccountStates((prev) => {\n        const previous = prev[accountId] ?? emptyAccountState();","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/components/codebuddy-suite/CodebuddySuiteCheckinModal.tsx#L109-L145","documentation":"The modal subscribes to a backend Workbuddy auto-checkin config-changed event (Tauri event listen). The promise returned by the listen API rejects when the event registration fails (backend not running, event name unknown, IPC channel closed), and this catch logs the failure instead of crashing the modal.","triggerScenarios":"The `.listen(...)`-style call inside CodebuddySuiteCheckinModal's effect rejects — e.g. the Tauri event system is unavailable, the backend command registering the listener fails, or the app is tearing down while the subscription is pending.","commonSituations":"Backend service not started yet when the modal mounts; renamed event payload/event name mismatch after an upgrade; webview reload races where the listener is disposed before registration resolves.","solutions":["Confirm the backend event is emitted with the exact event name the frontend listens for.","Ensure the backend/service providing the config events is initialized before the modal mounts, or retry the subscription.","Check that the unlisten/dispose logic (the `disposed` flag path) isn't racing registration; log which branch ran.","Add a fallback: also read current config once on mount so UI works even without the event subscription."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"await invoke('backend_ready').catch(() => { throw new Error('backend not ready; defer event subscription'); });","typeGuard":"function isConfigChangedEvent(e: Event): e is CustomEvent<CheckinConfig> {\n  return e instanceof CustomEvent && e.detail != null;\n}","tryCatchPattern":"listen(CHECKIN_CONFIG_EVENT, handler).then((stop) => {\n  if (disposed) stop(); else unlisten = stop;\n}).catch((err) => {\n  console.warn('[WorkbuddyAutoCheckin] 监听后端签到配置事件失败:', err);\n  loadConfigOnce(); // fallback to one-shot read\n});","preventionTips":["Subscribe only after confirming the backend service is ready","Keep event name strings in one shared module","Always provide a one-shot read fallback when live events are unavailable","Handle dispose racing registration (stop() if already disposed)"],"tags":["tauri","event-listener","ipc","subscription"],"backgroundTag":"event-listener-registration-failed","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}