jlcodes99/cockpit-tools · warning

[AccountStore] 写入持久化数据失败: ${name}

Error message

[AccountStore] 写入持久化数据失败: ${name}

What it means

The persist storage's setItem catches write failures. For QuotaExceededError specifically it schedules quota recovery (deletes caches) and optionally warns once; any other write error is warned with the key name. The store keeps running in memory even though nothing was persisted.

Source

Thrown at src/stores/useAccountStore.ts:71

      return null;
    }
  },
  setItem: (name: string, value: string) => {
    try {
      localStorage.setItem(name, value);
    } catch (error) {
      if (isQuotaExceededError(error)) {
        if (!accountStoreQuotaWarned) {
          console.warn(
            '[AccountStore] 本地缓存空间不足,已自动清理账号缓存并回退为仅内存态。',
            error
          );
          accountStoreQuotaWarned = true;
        }
        scheduleAccountStoreQuotaRecovery(name);
        return;
      }
      console.warn(`[AccountStore] 写入持久化数据失败: ${name}`, error);
    }
  },
  removeItem: (name: string) => {
    try {
      localStorage.removeItem(name);
    } catch (error) {
      console.warn(`[AccountStore] 删除持久化数据失败: ${name}`, error);
    }
  },
}));

function toPersistedTokenSnapshot(token: TokenData): TokenData {
  return {
    access_token: '',
    refresh_token: '',
    expires_in: 0,
    expiry_timestamp: 0,
    token_type: token.token_type || 'Bearer',

View on GitHub (pinned to 1ed8b77992)

Solutions

  1. Reduce persisted payload via the persist option partialize (store only needed fields)
  2. Let scheduleAccountStoreQuotaRecovery clear caches, then retry the write
  3. Check localStorage availability at startup and degrade gracefully
  4. Inspect the logged error name: QuotaExceededError vs SecurityError have different fixes

Example fix

// before
console.warn(`[AccountStore] 写入持久化数据失败: ${name}`, error);
// after
console.warn(`[AccountStore] 写入持久化数据失败: ${name}`, error);
if (error instanceof DOMException && error.name === 'QuotaExceededError') {
  scheduleAccountStoreQuotaRecovery(name);
}
Defensive patterns

Strategy: validation

Validate before calling

function estimatePersistSize(state: unknown): boolean {
  return JSON.stringify(state).length < 4_500_000; // stay under ~5MB quota
}

Type guard

function isQuotaError(error: unknown): error is DOMException {
  return error instanceof DOMException &&
    (error.name === 'QuotaExceededError' || error.name === 'NS_ERROR_DOM_QUOTA_REACHED');
}

Try / catch

setItem: (name: string, value: string) => {
  try { localStorage.setItem(name, value); }
  catch (error) {
    if (isQuotaError(error)) { scheduleAccountStoreQuotaRecovery(name); return; }
    console.warn(`[AccountStore] 写入持久化数据失败: ${name}`, error);
  }
}

Prevention

When it happens

Trigger: localStorage.setItem throws when persisting account state: quota exceeded by large account lists, storage disabled/private mode, or any storage exception from an embedded webview.

Common situations: Many large accounts inflating persisted JSON past quota; private browsing; storage blocked by browser policy after repeated quota violations.

Related errors


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