diff --git a/snapshot/src/core/cache.ts b/snapshot/src/core/cache.ts index c3c315d..f5870fb 100644 --- a/snapshot/src/core/cache.ts +++ b/snapshot/src/core/cache.ts @@ -4,13 +4,23 @@ export interface CacheState { } export async function readCache(path: string): Promise { + let text: string try { - const text = await Deno.readTextFile(path) - return JSON.parse(text) as CacheState + text = await Deno.readTextFile(path) } catch (err) { if (err instanceof Deno.errors.NotFound) return undefined throw err } + const parsed = JSON.parse(text) as unknown + if ( + !parsed || + typeof parsed !== 'object' || + typeof (parsed as { lastKnownGoodCount?: unknown }).lastKnownGoodCount !== 'number' || + !Array.isArray((parsed as { deletedCoords?: unknown }).deletedCoords) + ) { + throw new Error('Cache-File hat unbekanntes Format — bitte loeschen und neu starten') + } + return parsed as CacheState } export async function writeCache(path: string, state: CacheState): Promise { diff --git a/snapshot/tests/cache.test.ts b/snapshot/tests/cache.test.ts index 4b66e17..2eb630c 100644 --- a/snapshot/tests/cache.test.ts +++ b/snapshot/tests/cache.test.ts @@ -17,3 +17,18 @@ Deno.test('writeCache + readCache: round-trip', async () => { const out = await readCache(path) assertEquals(out, state) }) + +Deno.test('readCache wirft bei korruptem cache-file', async () => { + const dir = await Deno.makeTempDir() + const path = join(dir, 'cache.json') + await Deno.writeTextFile(path, '{"unsinn": 42}') + let threw = false + try { + await readCache(path) + } catch (err) { + threw = true + if (!(err instanceof Error)) throw err + if (!err.message.includes('Cache-File')) throw err + } + if (!threw) throw new Error('readCache haette werfen sollen') +})