{"record":{"id":"66cbb49493b5eac0","repo":"jlcodes99/cockpit-tools","slug":"workbuddyautocheckin-rust-66cbb4","errorCode":null,"errorMessage":"[WorkbuddyAutoCheckin] 保存配置到 Rust 后端失败:","messagePattern":"\\[WorkbuddyAutoCheckin\\] 保存配置到 Rust 后端失败:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/services/workbuddyAutoCheckinService.ts","lineNumber":127,"sourceCode":"    'migrate_workbuddy_auto_checkin_config',\n    { legacyConfig },\n  );\n  cacheConfigLocally(config, true);\n  return config;\n}\n\nexport async function saveWorkbuddyAutoCheckinConfigAsync(config: WorkbuddyAutoCheckinConfig): Promise<void> {\n  if (typeof window === 'undefined') {\n    cacheConfigLocally(config);\n    return;\n  }\n  await invoke('save_workbuddy_auto_checkin_config', { config });\n  cacheConfigLocally(config, true);\n}\n\nexport function saveWorkbuddyAutoCheckinConfig(config: WorkbuddyAutoCheckinConfig): void {\n  void saveWorkbuddyAutoCheckinConfigAsync(config).catch((err) => {\n    console.warn('[WorkbuddyAutoCheckin] 保存配置到 Rust 后端失败:', err);\n  });\n}\n\nexport function parseTimeToMinutes(timeStr: string): number {\n  const parts = timeStr.split(':').map(Number);\n  const h = parts[0] ?? 0;\n  const m = parts[1] ?? 0;\n  return h * 60 + m;\n}\n\nexport function formatMinutesToTime(minutes: number): string {\n  const h = Math.floor(minutes / 60) % 24;\n  const m = minutes % 60;\n  return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;\n}\n\nexport function getTodayDateString(): string {\n  const now = new Date();","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/services/workbuddyAutoCheckinService.ts#L109-L145","documentation":"saveWorkbuddyAutoCheckinConfig is the fire-and-forget wrapper around saveWorkbuddyAutoCheckinConfigAsync, which invokes 'save_workbuddy_auto_checkin_config' on the Rust backend. A rejected promise is caught and warned; the caller (e.g. ensureAccountSchedules) never sees the failure.","triggerScenarios":"invoke('save_workbuddy_auto_checkin_config') rejects: the Rust handler is missing/renamed, the config fails serialization in Rust, or IPC fails while the backend is unavailable.","commonSituations":"Frontend/backend version drift after renaming the command; corrupted backend config storage making the write fail; calling during shutdown before the Tauri runtime is ready.","solutions":["Check the Rust command name and registered handlers match 'save_workbuddy_auto_checkin_config'","Rebuild so the bundled Rust side supports the current config schema","Add a caller-visible error path (return the promise or surface a UI toast) instead of swallowing it","Retry the save after the backend reports ready"],"exampleFix":"// before\nvoid saveWorkbuddyAutoCheckinConfigAsync(config).catch((err) => {\n  console.warn('[WorkbuddyAutoCheckin] 保存配置到 Rust 后端失败:', err);\n});\n// after\nexport async function saveWorkbuddyAutoCheckinConfig(config: WorkbuddyAutoCheckinConfig): Promise<void> {\n  try {\n    await saveWorkbuddyAutoCheckinConfigAsync(config);\n  } catch (err) {\n    console.warn('[WorkbuddyAutoCheckin] 保存配置到 Rust 后端失败:', err);\n    throw err;\n  }\n}","handlingStrategy":"try-catch","validationCode":"if (!('__TAURI_INTERNALS__' in window)) {\n  console.warn('Tauri backend unavailable; skipping config save');\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await invoke('save_workbuddy_auto_checkin_config', { config });\n  cacheConfigLocally(config, true);\n} catch (err) {\n  console.warn('[WorkbuddyAutoCheckin] 保存配置到 Rust 后端失败:', err);\n  // surface to caller/UI so the save is not silently lost\n}","preventionTips":["Avoid fire-and-forget for config saves; propagate errors to the caller","Verify Rust handler registration for every command name","Rebuild frontend and backend together after schema changes","Retry the save once if the backend is temporarily unavailable"],"tags":["tauri","invoke","persistence"],"backgroundTag":"tauri-command-invoke-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"}