mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-22 07:41:23 -07:00
feat(ux): Surface internal errors via unified event system (#11803)
This commit is contained in:
@@ -64,9 +64,12 @@ import {
|
||||
loadEnvironment,
|
||||
migrateDeprecatedSettings,
|
||||
SettingScope,
|
||||
saveSettings,
|
||||
type SettingsFile,
|
||||
} from './settings.js';
|
||||
import { FatalConfigError, GEMINI_DIR, Storage } from '@google/gemini-cli-core';
|
||||
import { ExtensionEnablementManager } from './extensions/extensionEnablement.js';
|
||||
import { updateSettingsFilePreservingFormat } from '../utils/commentJson.js';
|
||||
|
||||
const MOCK_WORKSPACE_DIR = '/mock/workspace';
|
||||
// Use the (mocked) GEMINI_DIR for consistency
|
||||
@@ -96,6 +99,23 @@ vi.mock('fs', async (importOriginal) => {
|
||||
|
||||
vi.mock('./extension.js');
|
||||
|
||||
const mockCoreEvents = vi.hoisted(() => ({
|
||||
emitFeedback: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<typeof import('@google/gemini-cli-core')>();
|
||||
return {
|
||||
...actual,
|
||||
coreEvents: mockCoreEvents,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('../utils/commentJson.js', () => ({
|
||||
updateSettingsFilePreservingFormat: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('strip-json-comments', () => ({
|
||||
default: vi.fn((content) => content),
|
||||
}));
|
||||
@@ -2495,4 +2515,62 @@ describe('Settings Loading and Merging', () => {
|
||||
expect(setValueSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('saveSettings', () => {
|
||||
it('should save settings using updateSettingsFilePreservingFormat', () => {
|
||||
const mockUpdateSettings = vi.mocked(updateSettingsFilePreservingFormat);
|
||||
const settingsFile = {
|
||||
path: '/mock/settings.json',
|
||||
settings: { ui: { theme: 'dark' } },
|
||||
originalSettings: { ui: { theme: 'dark' } },
|
||||
} as unknown as SettingsFile;
|
||||
|
||||
saveSettings(settingsFile);
|
||||
|
||||
expect(mockUpdateSettings).toHaveBeenCalledWith('/mock/settings.json', {
|
||||
ui: { theme: 'dark' },
|
||||
});
|
||||
});
|
||||
|
||||
it('should create directory if it does not exist', () => {
|
||||
const mockFsExistsSync = vi.mocked(fs.existsSync);
|
||||
const mockFsMkdirSync = vi.mocked(fs.mkdirSync);
|
||||
mockFsExistsSync.mockReturnValue(false);
|
||||
|
||||
const settingsFile = {
|
||||
path: '/mock/new/dir/settings.json',
|
||||
settings: {},
|
||||
originalSettings: {},
|
||||
} as unknown as SettingsFile;
|
||||
|
||||
saveSettings(settingsFile);
|
||||
|
||||
expect(mockFsExistsSync).toHaveBeenCalledWith('/mock/new/dir');
|
||||
expect(mockFsMkdirSync).toHaveBeenCalledWith('/mock/new/dir', {
|
||||
recursive: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should emit error feedback if saving fails', () => {
|
||||
const mockUpdateSettings = vi.mocked(updateSettingsFilePreservingFormat);
|
||||
const error = new Error('Write failed');
|
||||
mockUpdateSettings.mockImplementation(() => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
const settingsFile = {
|
||||
path: '/mock/settings.json',
|
||||
settings: {},
|
||||
originalSettings: {},
|
||||
} as unknown as SettingsFile;
|
||||
|
||||
saveSettings(settingsFile);
|
||||
|
||||
expect(mockCoreEvents.emitFeedback).toHaveBeenCalledWith(
|
||||
'error',
|
||||
'There was an error saving your latest settings changes.',
|
||||
error,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
GEMINI_DIR,
|
||||
getErrorMessage,
|
||||
Storage,
|
||||
coreEvents,
|
||||
} from '@google/gemini-cli-core';
|
||||
import stripJsonComments from 'strip-json-comments';
|
||||
import { DefaultLight } from '../ui/themes/default-light.js';
|
||||
@@ -799,6 +800,10 @@ export function saveSettings(settingsFile: SettingsFile): void {
|
||||
settingsToSave as Record<string, unknown>,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error saving user settings file:', error);
|
||||
coreEvents.emitFeedback(
|
||||
'error',
|
||||
'There was an error saving your latest settings changes.',
|
||||
error,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user