mirror of
https://github.com/stablyai/orca.git
synced 2026-10-12 16:03:03 +00:00
fix(skills): observe archive abort errors before reading (#26246)
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { parseSkillTarHeader, SKILL_TAR_BLOCK_BYTES } from './skill-package-tar'
|
||||
import { mkdtemp, rm } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
import {
|
||||
openSkillTarGzip,
|
||||
parseSkillTarHeader,
|
||||
SKILL_TAR_BLOCK_BYTES,
|
||||
writeSkillTarGzip
|
||||
} from './skill-package-tar'
|
||||
|
||||
function writeOctal(header: Buffer, offset: number, length: number, value: number): void {
|
||||
header.write(`${value.toString(8).padStart(length - 1, '0')}\0`, offset, length, 'ascii')
|
||||
@@ -62,3 +70,26 @@ describe('skill package tar envelope', () => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('skill tar reader error ownership', () => {
|
||||
it('observes an abort after the pipeline completes before the first reader request', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'orca-skill-tar-abort-'))
|
||||
try {
|
||||
const archivePath = join(root, 'archive.tar.gz')
|
||||
await writeSkillTarGzip(archivePath, [
|
||||
{ path: 'SKILL.md', size: 1, executable: false, bytes: Buffer.from('x') }
|
||||
])
|
||||
const archive = await openSkillTarGzip(archivePath)
|
||||
await archive.archiveIdentity
|
||||
const failure = Object.assign(new Error('staging directory already exists'), {
|
||||
code: 'EEXIST'
|
||||
})
|
||||
archive.abort(failure)
|
||||
// Observe destruction before lazily attaching the reader's error listener.
|
||||
await new Promise<void>((resolve) => setImmediate(resolve))
|
||||
await expect(archive.reader.readExact(SKILL_TAR_BLOCK_BYTES)).rejects.toBe(failure)
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -262,6 +262,8 @@ export async function openSkillTarGzip(archivePath: string): Promise<{
|
||||
}
|
||||
})
|
||||
const gunzip = createGunzip()
|
||||
// Observe late aborts before the archive reader starts.
|
||||
gunzip.on('error', () => undefined)
|
||||
const completion = pipeline(source, verifier, gunzip)
|
||||
const archiveIdentity = completion.then(() => ({
|
||||
archiveSha256: archiveHash.digest('hex'),
|
||||
|
||||
Reference in New Issue
Block a user