FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix: preserve streamed size-limit errors when response cancellation f… · vercel/ai@7fbfc6d · GitHub

/ ai Public

Commit 7fbfc6d

Browse files
authored
fix: preserve streamed size-limit errors when response cancellation fails (#18695)
## Background Streamed responses exceeding the byte limit could reject with a cancellation error instead of the intended DownloadError. ## Root Cause The streamed cleanup path awaited reader.cancel() without catching its rejection, allowing the cleanup failure to replace the confirmed size-limit DownloadError. ## Summary Ignored reader cancellation failures while retaining lock release, added a patch changeset, and removed reproduction-only artifacts. ## Testing Added regression coverage verifying cancellation is attempted, the reader lock is released, and the original DownloadError is preserved. ## End-to-end Validation - `pnpm -C examples/ai-functions exec tsx src/reproduction/issue-18571-stream-size-limit-cancel-error.ts` exited successfully after rebuilding provider-utils; cancellation was attempted, the lock was released, and the expected DownloadError was preserved. ## Related Issues Fixes #18571 Closes #18682 Closes #18572 --------- Co-authored-by: ai-sdk-factory <308175966+ai-sdk-factory@users.noreply.github.com> Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com> Co-authored-by: teamleaderleo <13091533+teamleaderleo@users.noreply.github.com>
1 parent b1cbe57 commit 7fbfc6d

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

‎.changeset/tidy-streams-rest.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@ai-sdk/provider-utils': patch
3+
---
4+
5+
Preserve streamed download size-limit errors when response cancellation fails.

‎packages/provider-utils/src/read-response-with-size-limit.test.ts‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,42 @@ describe('readResponseWithSizeLimit', () => {
121121
});
122122
});
123123

124+
it('should preserve streamed size-limit errors when cancellation fails', async () => {
125+
const cancelError = new Error('cancel failed');
126+
let cancelled = false;
127+
const body = new ReadableStream<Uint8Array>({
128+
start(controller) {
129+
controller.enqueue(new Uint8Array([1, 2]));
130+
},
131+
cancel() {
132+
cancelled = true;
133+
return Promise.reject(cancelError);
134+
},
135+
});
136+
const response = {
137+
headers: new Headers(),
138+
body,
139+
} as unknown as Response;
140+
141+
await expect(
142+
readResponseWithSizeLimit({
143+
response,
144+
url: 'http://example.com/streaming',
145+
maxBytes: 1,
146+
}),
147+
).rejects.toSatisfy((error: unknown) => {
148+
expect(error).not.toBe(cancelError);
149+
expect(DownloadError.isInstance(error)).toBe(true);
150+
expect((error as DownloadError).message).toBe(
151+
'Download of http://example.com/streaming exceeded maximum size of 1 bytes.',
152+
);
153+
return true;
154+
});
155+
156+
expect(cancelled).toBe(true);
157+
expect(body.locked).toBe(false);
158+
});
159+
124160
it('should handle lying Content-Length (says small, sends large)', async () => {
125161
const largeBody = new Uint8Array(200);
126162
largeBody.fill(42);

‎packages/provider-utils/src/read-response-with-size-limit.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ export async function readResponseWithSizeLimit({
8484
} finally {
8585
try {
8686
await reader.cancel();
87+
} catch {
88+
// Ignore cancel errors so the original rejection is preserved.
8789
} finally {
8890
reader.releaseLock();
8991
}

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL