diff options
| author | Hiroaki Mitsuyoshi <[email protected]> | 2025-08-09 15:59:22 +0900 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-08-09 06:59:22 +0000 |
| commit | 6487cc16895976ef6c983f8beca08a64addb6688 (patch) | |
| tree | e2d4d06bc37331d0c36a1c27442457d42f81d385 /packages/core/src | |
| parent | 191cc01bf5833a4c7636f8fc4d9b4c5066982822 (diff) | |
feat(chat): Add overwrite confirmation dialog to `/chat save` (#5686)
Co-authored-by: Jacob Richman <[email protected]>
Diffstat (limited to 'packages/core/src')
| -rw-r--r-- | packages/core/src/core/logger.test.ts | 46 | ||||
| -rw-r--r-- | packages/core/src/core/logger.ts | 23 |
2 files changed, 69 insertions, 0 deletions
diff --git a/packages/core/src/core/logger.test.ts b/packages/core/src/core/logger.test.ts index 3f243b52..d032e2d4 100644 --- a/packages/core/src/core/logger.test.ts +++ b/packages/core/src/core/logger.test.ts @@ -565,6 +565,52 @@ describe('Logger', () => { }); }); + describe('checkpointExists', () => { + const tag = 'exists-test'; + let taggedFilePath: string; + + beforeEach(() => { + taggedFilePath = path.join(TEST_GEMINI_DIR, `checkpoint-${tag}.json`); + }); + + it('should return true if the checkpoint file exists', async () => { + await fs.writeFile(taggedFilePath, '{}'); + const exists = await logger.checkpointExists(tag); + expect(exists).toBe(true); + }); + + it('should return false if the checkpoint file does not exist', async () => { + const exists = await logger.checkpointExists('non-existent-tag'); + expect(exists).toBe(false); + }); + + it('should throw an error if logger is not initialized', async () => { + const uninitializedLogger = new Logger(testSessionId); + uninitializedLogger.close(); + + await expect(uninitializedLogger.checkpointExists(tag)).rejects.toThrow( + 'Logger not initialized. Cannot check for checkpoint existence.', + ); + }); + + it('should re-throw an error if fs.access fails for reasons other than not existing', async () => { + vi.spyOn(fs, 'access').mockRejectedValueOnce( + new Error('EACCES: permission denied'), + ); + const consoleErrorSpy = vi + .spyOn(console, 'error') + .mockImplementation(() => {}); + + await expect(logger.checkpointExists(tag)).rejects.toThrow( + 'EACCES: permission denied', + ); + expect(consoleErrorSpy).toHaveBeenCalledWith( + `Failed to check checkpoint existence for ${taggedFilePath}:`, + expect.any(Error), + ); + }); + }); + describe('close', () => { it('should reset logger state', async () => { await logger.logMessage(MessageSenderType.USER, 'A message'); diff --git a/packages/core/src/core/logger.ts b/packages/core/src/core/logger.ts index 9f4622e7..f4857f47 100644 --- a/packages/core/src/core/logger.ts +++ b/packages/core/src/core/logger.ts @@ -310,6 +310,29 @@ export class Logger { } } + async checkpointExists(tag: string): Promise<boolean> { + if (!this.initialized) { + throw new Error( + 'Logger not initialized. Cannot check for checkpoint existence.', + ); + } + const filePath = this._checkpointPath(tag); + try { + await fs.access(filePath); + return true; + } catch (error) { + const nodeError = error as NodeJS.ErrnoException; + if (nodeError.code === 'ENOENT') { + return false; + } + console.error( + `Failed to check checkpoint existence for ${filePath}:`, + error, + ); + throw error; + } + } + close(): void { this.initialized = false; this.logFilePath = undefined; |
