jlcodes99/cockpit-tools · warning

[WorkbuddyAutoCheckin] 监听后端签到日志事件失败:

Error message

[WorkbuddyAutoCheckin] 监听后端签到日志事件失败:

What it means

WorkbuddyAutoCheckinConfigModal subscribes to backend auto-checkin log events on mount. If the listener registration promise rejects (event channel unavailable or backend not ready), the catch logs the failure; the modal then only updates logs via manual loads rather than live events.

Source

Thrown at src/components/codebuddy-suite/WorkbuddyAutoCheckinConfigModal.tsx:96

          setLogsLoading(false);
        }
      }
    };

    void loadLogs();
    const handleLogsChange = () => {
      void loadLogs();
    };
    void listen(WORKBUDDY_AUTO_CHECKIN_LOGS_CHANGED_EVENT, handleLogsChange)
      .then((stopListening) => {
        if (disposed) {
          stopListening();
        } else {
          unlisten = stopListening;
        }
      })
      .catch((err) => {
        console.warn('[WorkbuddyAutoCheckin] 监听后端签到日志事件失败:', err);
      });
    return () => {
      disposed = true;
      unlisten?.();
    };
  }, []);

  const handleSave = async () => {
    const startMin = parseTimeToMinutes(startTime);
    const endMin = parseTimeToMinutes(endTime);

    if (startMin > endMin) {
      setError(t('workbuddy.checkin.timeRangeError', '开始时间不能晚于结束时间'));
      return;
    }

    setSaving(true);
    setError(null);

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Verify both frontend and backend use the identical event name string.
  2. Delay or retry subscription until the backend confirms readiness (e.g. after an initial health/config load succeeds).
  3. Ensure cleanup handles the case where the listen promise resolves with the unlisten function after dispose (the `stopListening` branch).
  4. Fall back to polling `loadLogs` when live subscription fails.
Defensive patterns

Strategy: retry

Validate before calling

const backendReady = await invoke('backend_ready').then(() => true).catch(() => false);
if (!backendReady) scheduleSubscribeRetry(1000);

Type guard

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

Try / catch

const subscribe = (attempt = 0) =>
  listen(LOGS_EVENT, handler)
    .then((stop) => { disposed ? stop() : (unlisten = stop); })
    .catch((err) => {
      if (attempt < 3) setTimeout(() => subscribe(attempt + 1), 1000 * 2 ** attempt);
      else console.warn('[WorkbuddyAutoCheckin] 监听后端签到日志事件失败:', err);
    });

Prevention

When it happens

Trigger: The event-listen promise rejects in the modal's mount effect: backend event emitter not registered, wrong event name, or the effect's cleanup ran before registration resolved (unlisten returned as the promise value).

Common situations: Modal opened before backend service warm-up; event name refactored on one side only; hot-reload/dev webview reload killing pending subscriptions.

Related errors


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