Files
deepseek-harness/packages/fs/tool-fs/tests/error.spec.ts
_Kerman 1ee167aeac feat(fs): append recovery remedy to guarded-mutation errors
write/edit failures with FS_STALE_VERSION or FS_NOT_OBSERVED now reach the
model with the correct recovery instruction appended (re-read / read, then
retry) while preserving the structured code and chaining the cause. The
edit-intent waterfall sits inside the same try, so the policy's
FS_NOT_OBSERVED refusal is remediated too. Re-recorded the fs-policy-reject
keyless snapshot and the bilingual README pairs.
2026-08-03 20:08:41 +08:00

36 lines
1.5 KiB
TypeScript

/**
* Unit tests for the model-facing error remediation: the remedy appended to
* guarded-mutation failures, code preservation, and passthrough behavior.
*/
import { describe, expect, it } from 'vitest'
import { FsError } from '@deepseek-ai/dsh-fs'
import { remediateFsError } from '../src/error.ts'
describe('remediateFsError', () => {
it('appends the re-read remedy to FS_STALE_VERSION, preserving the code and chaining the cause', () => {
const original = new FsError('cannot edit "x": file changed since it was read', 'FS_STALE_VERSION')
const remedied = remediateFsError(original) as FsError
expect(remedied).toBeInstanceOf(FsError)
expect(remedied.message).toBe('cannot edit "x": file changed since it was read — re-read the file, then retry')
expect(remedied.code).toBe('FS_STALE_VERSION')
expect(remedied.cause).toBe(original)
})
it('appends the read remedy to FS_NOT_OBSERVED', () => {
const remedied = remediateFsError(new FsError('edit requires reading "x" first', 'FS_NOT_OBSERVED')) as FsError
expect(remedied.message).toBe('edit requires reading "x" first — read the file, then retry')
expect(remedied.code).toBe('FS_NOT_OBSERVED')
})
it('leaves other FsError codes untouched', () => {
const original = new FsError('no match anywhere', 'FS_EDIT_NOT_FOUND')
expect(remediateFsError(original)).toBe(original)
})
it('leaves non-FsError values untouched', () => {
const original = new Error('boom')
expect(remediateFsError(original)).toBe(original)
})
})