{"record":{"id":"5c048e5b97cfa996","repo":"jlcodes99/cockpit-tools","slug":"accountstore","errorCode":null,"errorMessage":"[AccountStore] 清理超限缓存失败:","messagePattern":"\\[AccountStore\\] 清理超限缓存失败:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/stores/useAccountStore.ts","lineNumber":40,"sourceCode":"      error.name === 'QuotaExceededError' ||\n      error.code === 22 ||\n      error.code === 1014\n    );\n  }\n  const message = String(error);\n  return message.includes('QuotaExceededError') || message.includes('quota');\n}\n\nfunction scheduleAccountStoreQuotaRecovery(storageKey: string) {\n  if (typeof window === 'undefined' || accountStoreQuotaCleanupScheduled) return;\n  accountStoreQuotaCleanupScheduled = true;\n  setTimeout(() => {\n    try {\n      localStorage.removeItem(storageKey);\n      localStorage.removeItem(LEGACY_ACCOUNTS_CACHE_KEY);\n      localStorage.removeItem(LEGACY_CURRENT_ACCOUNT_CACHE_KEY);\n    } catch (error) {\n      console.warn('[AccountStore] 清理超限缓存失败:', error);\n    } finally {\n      accountStoreQuotaCleanupScheduled = false;\n    }\n  }, 0);\n}\n\nconst accountStoreStorage = createJSONStorage(() => ({\n  getItem: (name: string) => {\n    try {\n      return localStorage.getItem(name);\n    } catch (error) {\n      console.warn(`[AccountStore] 读取持久化数据失败: ${name}`, error);\n      return null;\n    }\n  },\n  setItem: (name: string, value: string) => {\n    try {\n      localStorage.setItem(name, value);","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src/stores/useAccountStore.ts#L22-L58","documentation":"scheduleAccountStoreQuotaRecovery defers a setTimeout(0) cleanup that removes the account store cache key and two legacy keys to recover from a QuotaExceededError during a persist write. If even the removals fail, the error is warned and the schedule flag is reset in finally.","triggerScenarios":"localStorage.removeItem throws during quota recovery — storage disabled, page in a blocked-storage context, or the environment throwing on any storage access after a quota violation.","commonSituations":"Safari private mode where all storage APIs throw; embedded webviews with storage partitioned off; persistent quota pressure from other large keys.","solutions":["Verify storage availability once at startup and disable persistence when unavailable","Clear site data manually to reset the quota","Keep the finally-based flag reset so recovery can be rescheduled later","Reduce persisted state size (partialize the zustand store) to avoid quota pressure"],"exampleFix":"// before\n} catch (error) {\n  console.warn('[AccountStore] 清理超限缓存失败:', error);\n}\n// after\n} catch (error) {\n  console.warn('[AccountStore] 清理超限缓存失败:', error);\n  console.warn('[AccountStore] 请手动清除站点数据以恢复账号缓存');\n}","handlingStrategy":"try-catch","validationCode":"function storageWritable(): boolean {\n  try { localStorage.setItem('__probe__', '1'); localStorage.removeItem('__probe__'); return true; }\n  catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  localStorage.removeItem(storageKey);\n  localStorage.removeItem(LEGACY_ACCOUNTS_CACHE_KEY);\n  localStorage.removeItem(LEGACY_CURRENT_ACCOUNT_CACHE_KEY);\n} catch (error) {\n  console.warn('[AccountStore] 清理超限缓存失败:', error);\n} finally {\n  accountStoreQuotaCleanupScheduled = false;\n}","preventionTips":["Use partialize on the persist store to keep persisted state small","Probe storage availability once and disable persistence if blocked","Keep cleanup idempotent and always reset the scheduling flag in finally","Advise manual site-data clearing when automatic recovery fails"],"tags":["localstorage","quota","recovery"],"backgroundTag":"localstorage-quota-exceeded","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"}