fix: preserve transport cause diagnostics
This commit is contained in:
@@ -57,10 +57,6 @@ function requestId(headers: Headers): ReturnType<typeof ProviderRequestId> | und
|
|||||||
return value === null || value.length === 0 ? undefined : ProviderRequestId(value)
|
return value === null || value.length === 0 ? undefined : ProviderRequestId(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function errorMessage(value: unknown): string {
|
|
||||||
return value instanceof Error ? value.message : String(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map an HTTP status to a stable LlmError code.
|
* Map an HTTP status to a stable LlmError code.
|
||||||
* @param status - status of a non-2xx provider response.
|
* @param status - status of a non-2xx provider response.
|
||||||
@@ -144,7 +140,7 @@ export class DeepSeekAdapter extends LlmAdapter {
|
|||||||
throw new LlmError('DeepSeek request aborted by caller', 'ABORTED', { cause: error })
|
throw new LlmError('DeepSeek request aborted by caller', 'ABORTED', { cause: error })
|
||||||
}
|
}
|
||||||
if (error instanceof LlmError) throw error
|
if (error instanceof LlmError) throw error
|
||||||
throw new LlmError(`DeepSeek transport failed: ${errorMessage(error)}`, 'TRANSPORT', { cause: error })
|
throw new LlmError(`DeepSeek API stream from ${this.options.baseURL} failed`, 'TRANSPORT', { cause: error })
|
||||||
} finally {
|
} finally {
|
||||||
consumer.abort('DeepSeek stream consumer stopped')
|
consumer.abort('DeepSeek stream consumer stopped')
|
||||||
if (!exhausted && iterator.return !== undefined) {
|
if (!exhausted && iterator.return !== undefined) {
|
||||||
|
|||||||
@@ -373,14 +373,20 @@ describe('DeepSeekAdapter against a mock server', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('rejects with STREAM_CLOSED when the server drops mid-stream', async () => {
|
it('classifies an abrupt body close as TRANSPORT and retains its cause', async () => {
|
||||||
const server = await mockServer([{
|
const server = await mockServer([{
|
||||||
kind: 'close-early',
|
kind: 'close-early',
|
||||||
events: ['{"choices":[{"delta":{"content":"par"}}]}'],
|
events: ['{"choices":[{"delta":{"content":"par"}}]}'],
|
||||||
}])
|
}])
|
||||||
const ctx = await harness(server.url)
|
const ctx = await harness(server.url)
|
||||||
await expect(assemble(ctx,{ model: 'deepseek-v4-flash', messages: [] }))
|
let caught: unknown
|
||||||
.rejects.toThrow(/terminated|socket|without \[DONE\]/)
|
try {
|
||||||
|
await assemble(ctx,{ model: 'deepseek-v4-flash', messages: [] })
|
||||||
|
} catch (error: unknown) {
|
||||||
|
caught = error
|
||||||
|
}
|
||||||
|
expect(caught).toMatchObject({ code: 'TRANSPORT' })
|
||||||
|
expect(errorChain(caught)).toMatch(/terminated|socket|without \[DONE\]/)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('aborts mid-stream via the request signal', async () => {
|
it('aborts mid-stream via the request signal', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user