jlcodes99/cockpit-tools · warning

[WorkbuddyAutoCheckin] 监听后端签到配置事件失败:

Error message

[WorkbuddyAutoCheckin] 监听后端签到配置事件失败:

What it means

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.

Source

Thrown at src/components/codebuddy-suite/CodebuddySuiteCheckinModal.tsx:127

    const handleConfigChange = () => {
      void getWorkbuddyAutoCheckinConfigAsync().then((nextConfig) => {
        if (!disposed) {
          setAutoCheckinConfig(nextConfig);
        }
      });
    };
    handleConfigChange();
    window.addEventListener(WORKBUDDY_AUTO_CHECKIN_CONFIG_CHANGED_EVENT, handleConfigChange);
    void listen(WORKBUDDY_AUTO_CHECKIN_CONFIG_CHANGED_EVENT, handleConfigChange)
      .then((stopListening) => {
        if (disposed) {
          stopListening();
        } else {
          unlisten = stopListening;
        }
      })
      .catch((err) => {
        console.warn('[WorkbuddyAutoCheckin] 监听后端签到配置事件失败:', err);
      });
    return () => {
      disposed = true;
      unlisten?.();
      window.removeEventListener(WORKBUDDY_AUTO_CHECKIN_CONFIG_CHANGED_EVENT, handleConfigChange);
    };
  }, []);

  useEffect(() => {
    if (accounts.length > 0) {
      void fetchAllStatus();
    }
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const updateAccountState = useCallback(
    (accountId: string, patch: Partial<AccountCheckinState>) => {
      setAccountStates((prev) => {
        const previous = prev[accountId] ?? emptyAccountState();

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Confirm the backend event is emitted with the exact event name the frontend listens for.
  2. Ensure the backend/service providing the config events is initialized before the modal mounts, or retry the subscription.
  3. Check that the unlisten/dispose logic (the `disposed` flag path) isn't racing registration; log which branch ran.
  4. Add a fallback: also read current config once on mount so UI works even without the event subscription.

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

await invoke('backend_ready').catch(() => { throw new Error('backend not ready; defer event subscription'); });

Type guard

function isConfigChangedEvent(e: Event): e is CustomEvent<CheckinConfig> {
  return e instanceof CustomEvent && e.detail != null;
}

Try / catch

listen(CHECKIN_CONFIG_EVENT, handler).then((stop) => {
  if (disposed) stop(); else unlisten = stop;
}).catch((err) => {
  console.warn('[WorkbuddyAutoCheckin] 监听后端签到配置事件失败:', err);
  loadConfigOnce(); // fallback to one-shot read
});

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jlcodes99/cockpit-tools@1ed8b77992 (2026-09-05). Data as JSON: /api/errors/f0363fee02b4e64c. Report an issue: GitHub.