jlcodes99/cockpit-tools · warning

[WorkbuddyAutoCheckin] 读取后端签到日志失败:

Error message

[WorkbuddyAutoCheckin] 读取后端签到日志失败:

What it means

`loadLogs` fetches Workbuddy auto-checkin logs from the backend via `getWorkbuddyAutoCheckinLogsAsync()`. On rejection the warning is logged and `logsError` is set so the modal can render an error message instead of stale logs.

Source

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

  const [expandedLogIds, setExpandedLogIds] = useState<Record<string, boolean>>({});

  useEffect(() => {
    let disposed = false;
    let unlisten: (() => void) | undefined;
    let requestId = 0;

    const loadLogs = async () => {
      const currentRequestId = ++requestId;
      setLogsLoading(true);
      setLogsError(null);

      try {
        const nextLogs = await getWorkbuddyAutoCheckinLogsAsync();
        if (!disposed && currentRequestId === requestId) {
          setLogs(nextLogs);
        }
      } catch (err) {
        console.warn('[WorkbuddyAutoCheckin] 读取后端签到日志失败:', err);
        if (!disposed && currentRequestId === requestId) {
          setLogsError(err instanceof Error ? err.message : String(err));
        }
      } finally {
        if (!disposed && currentRequestId === requestId) {
          setLogsLoading(false);
        }
      }
    };

    void loadLogs();
    const handleLogsChange = () => {
      void loadLogs();
    };
    void listen(WORKBUDDY_AUTO_CHECKIN_LOGS_CHANGED_EVENT, handleLogsChange)
      .then((stopListening) => {
        if (disposed) {
          stopListening();

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Read `logsError`/the console warning for the underlying backend rejection and fix it (file permissions, storage init).
  2. Initialize the log storage lazily on first access in the backend so a missing store returns an empty list rather than rejecting.
  3. Verify the backend command name/signature matches the frontend binding after upgrades.
  4. Retry the load with backoff if the failure is transient (backend busy).

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

if (disposed || currentRequestId !== requestId) return; // skip stale loads

Type guard

function isCheckinLog(v: unknown): v is CheckinLog {
  return typeof v === 'object' && v !== null && 'timestamp' in v && 'status' in v;
}

Try / catch

try {
  const logs = await getWorkbuddyAutoCheckinLogsAsync();
  if (!disposed && currentRequestId === requestId) setLogs(logs);
} catch (err) {
  setLogsError(err instanceof Error ? err.message : String(err));
} finally {
  if (!disposed && currentRequestId === requestId) setLogsLoading(false);
}

Prevention

When it happens

Trigger: The async logs fetch rejects: backend command error, backend storage/log file unreadable or corrupt, IPC failure, or a stale request racing with dispose (guarded by requestId/disposed checks).

Common situations: First run with no log storage initialized; log file locked by another process; backend upgraded with changed log schema; rapid modal open/close causing request-ID mismatches (which are silently ignored, not errors).

Related errors


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