@@ -6,9 +6,35 @@ import {
66 extractProviderErrorInfo ,
77 extractProviderRequestId ,
88 ProviderHttpError ,
9+ readProviderBinaryResponse ,
910 readProviderJsonResponse ,
1011} from "./provider-http-errors.js" ;
1112
13+ function createStreamingBinaryResponse ( params : {
14+ chunkCount : number ;
15+ chunkSize : number ;
16+ byte : number ;
17+ } ) : { response : Response ; getReadCount : ( ) => number } {
18+ let reads = 0 ;
19+ const stream = new ReadableStream < Uint8Array > ( {
20+ pull ( controller ) {
21+ if ( reads >= params . chunkCount ) {
22+ controller . close ( ) ;
23+ return ;
24+ }
25+ reads += 1 ;
26+ controller . enqueue ( new Uint8Array ( params . chunkSize ) . fill ( params . byte ) ) ;
27+ } ,
28+ } ) ;
29+ return {
30+ response : new Response ( stream , {
31+ status : 200 ,
32+ headers : { "Content-Type" : "audio/mpeg" } ,
33+ } ) ,
34+ getReadCount : ( ) => reads ,
35+ } ;
36+ }
37+
1238describe ( "provider error utils" , ( ) => {
1339 it ( "formats nested provider error details with request ids" , async ( ) => {
1440 const response = new Response (
@@ -147,4 +173,20 @@ describe("provider error utils", () => {
147173 "Provider catalog failed: malformed JSON response" ,
148174 ) ;
149175 } ) ;
176+
177+ it ( "caps successful binary responses instead of buffering oversized bodies" , async ( ) => {
178+ const streamed = createStreamingBinaryResponse ( {
179+ chunkCount : 20 ,
180+ chunkSize : 1024 ,
181+ byte : 121 ,
182+ } ) ;
183+
184+ await expect (
185+ readProviderBinaryResponse ( streamed . response , "Provider TTS failed" , "audio" , {
186+ maxBytes : 2048 ,
187+ } ) ,
188+ ) . rejects . toThrow ( "Provider TTS failed: audio response exceeds 2048 bytes" ) ;
189+
190+ expect ( streamed . getReadCount ( ) ) . toBeLessThan ( 20 ) ;
191+ } ) ;
150192} ) ;
0 commit comments