fix(host): race directory reads against the caller's signal; report aborts as cancelled
Every filesystem await in the browse scan (opendir and each read) now races the signal through raceAbort, so a stalled network open/read stops with a departed caller and an already-aborted request rejects even for an empty level; the abandoned settlement is swallowed and an abandoned open that still mints a handle is closed, never leaked. apiproxy maps an aborted listing to the cancelled wire code, matching pickDirectory and command.execute, instead of reporting a false internal failure. The fixture spec call sites gain the wire signal argument the previous commit's static lane flagged.
This commit is contained in:
@@ -193,6 +193,20 @@ describe('host.listDirectory / host.createDirectory', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('reports an aborted listing as cancelled, like the other signal-following RPCs', async () => {
|
||||
const { api } = await harness(undefined, {
|
||||
kind: 'browse',
|
||||
list: (_path, signal) => new Promise((_resolve, reject) => {
|
||||
signal?.addEventListener('abort', () => { reject(new Error('scan aborted')) }, { once: true })
|
||||
}),
|
||||
createDirectory: async () => '/never',
|
||||
})
|
||||
const abort = new AbortController()
|
||||
const pending = api.host.listDirectory(request({}), abort.signal)
|
||||
abort.abort()
|
||||
expect((await pending).result).toMatchObject({ ok: false, error: { code: 'cancelled' } })
|
||||
})
|
||||
|
||||
it('refuses the browse RPCs under a native composition', async () => {
|
||||
const { api } = await harness()
|
||||
expect((await api.host.listDirectory(request({}), new AbortController().signal)).result).toMatchObject({
|
||||
|
||||
Reference in New Issue
Block a user