fix(settings): 防止设置读取失败后覆盖用户配置

Co-authored-by: zipg <4047349+zipg@users.noreply.github.com>
This commit is contained in:
zipgandzipg authored and GitHub committed 2026-08-10 10:24:42 +08:00
1 parent 0c9b6c7e1d
commit 6c2ca2eadd
2 files changed
+51 -1

No files matched your search

+47
View File
@@ -527,6 +527,53 @@ describe("settingsStore MCP policy persistence", () => {
});
});
describe("settingsStore persisted settings initialization", () => {
beforeEach(() => {
vi.resetModules();
setActivePinia(createPinia());
});
it("does not treat an editor settings read failure as an empty record", async () => {
const loadEditorSettings = vi.fn().mockRejectedValue(new Error("storage temporarily unavailable"));
const saveEditorSettings = vi.fn().mockResolvedValue(undefined);
vi.doMock("@/lib/backend/api", () => ({ loadEditorSettings, saveEditorSettings }));
const { useSettingsStore } = await import("@/stores/settingsStore");
const store = useSettingsStore();
await expect(store.initEditorSettings()).rejects.toThrow("storage temporarily unavailable");
expect(store.isEditorSettingsLoaded).toBe(false);
expect(saveEditorSettings).not.toHaveBeenCalled();
});
it("can retry editor settings initialization without losing saved values", async () => {
const loadEditorSettings = vi.fn().mockRejectedValueOnce(new Error("storage temporarily unavailable")).mockResolvedValueOnce({
fontSize: 17,
theme: "xcode-dark",
executeMode: "all",
executeModeDefaultVersion: 1,
updateNotificationsEnabled: false,
});
const saveEditorSettings = vi.fn().mockResolvedValue(undefined);
vi.doMock("@/lib/backend/api", () => ({ loadEditorSettings, saveEditorSettings }));
const { useSettingsStore } = await import("@/stores/settingsStore");
const store = useSettingsStore();
await expect(store.initEditorSettings()).rejects.toThrow("storage temporarily unavailable");
await store.initEditorSettings();
expect(store.isEditorSettingsLoaded).toBe(true);
expect(store.editorSettings).toMatchObject({
fontSize: 17,
theme: "xcode-dark",
executeMode: "all",
updateNotificationsEnabled: false,
});
expect(saveEditorSettings).not.toHaveBeenCalled();
});
});
describe("settingsStore sidebar connection sort persistence", () => {
beforeEach(() => {
vi.resetModules();
+4 -1
View File
@@ -1191,7 +1191,10 @@ export const useSettingsStore = defineStore("settings", () => {
async function initEditorSettings() {
if (isEditorSettingsLoaded.value) return;
const saved = await api.loadEditorSettings().catch(() => null);
// A read failure is not the same as an empty settings record. Keeping the
// store unloaded prevents startup migrations from persisting defaults over
// settings that are temporarily unavailable.
const saved = await api.loadEditorSettings();
if (saved && typeof saved === "object" && !Array.isArray(saved)) {
const savedSettings = saved as Partial<EditorSettings>;
const normalized = normalizeEditorSettings(savedSettings);