@@ -73,171 +73,154 @@ export const createClient = (config: Config = {}): Client => {
7373 } ;
7474
7575 const request : Client [ 'request' ] = async ( options ) => {
76- const { opts, url } = await beforeRequest ( options ) ;
77- const requestInit : ReqInit = {
78- redirect : 'follow' ,
79- ...opts ,
80- body : getValidRequestBody ( opts ) ,
81- } ;
82-
83- let request = new Request ( url , requestInit ) ;
84-
85- for ( const fn of interceptors . request . fns ) {
86- if ( fn ) {
87- request = await fn ( request , opts ) ;
88- }
89- }
76+ const throwOnError = options . throwOnError ?? _config . throwOnError ;
77+ const responseStyle = options . responseStyle ?? _config . responseStyle ;
9078
91- // fetch must be assigned here, otherwise it would throw the error:
92- // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
93- const _fetch = opts . fetch ! ;
94- let response : Response ;
79+ let request : Request | undefined ;
80+ let response : Response | undefined ;
9581
9682 try {
97- response = await _fetch ( request ) ;
98- } catch ( error ) {
99- // Handle fetch exceptions (AbortError, network errors, etc.)
100- let finalError = error ;
83+ const { opts, url } = await beforeRequest ( options ) ;
84+ const requestInit : ReqInit = {
85+ redirect : 'follow' ,
86+ ...opts ,
87+ body : getValidRequestBody ( opts ) ,
88+ } ;
10189
102- for ( const fn of interceptors . error . fns ) {
90+ request = new Request ( url , requestInit ) ;
91+
92+ for ( const fn of interceptors . request . fns ) {
10393 if ( fn ) {
104- finalError = ( await fn ( error , undefined as any , request , opts ) ) as unknown ;
94+ request = await fn ( request , opts ) ;
10595 }
10696 }
10797
108- finalError = finalError || ( { } as unknown ) ;
98+ // fetch must be assigned here, otherwise it would throw the error:
99+ // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
100+ const _fetch = opts . fetch ! ;
109101
110- if ( opts . throwOnError ) {
111- throw finalError ;
112- }
113-
114- // Return error response
115- return opts . responseStyle === 'data'
116- ? undefined
117- : {
118- error : finalError ,
119- request,
120- response : undefined as any ,
121- } ;
122- }
102+ response = await _fetch ( request ) ;
123103
124- for ( const fn of interceptors . response . fns ) {
125- if ( fn ) {
126- response = await fn ( response , request , opts ) ;
104+ for ( const fn of interceptors . response . fns ) {
105+ if ( fn ) {
106+ response = await fn ( response , request , opts ) ;
107+ }
127108 }
128- }
129-
130- const result = {
131- request,
132- response,
133- } ;
134109
135- if ( response . ok ) {
136- const parseAs =
137- ( opts . parseAs === 'auto'
138- ? getParseAs ( response . headers . get ( 'Content-Type' ) )
139- : opts . parseAs ) ?? 'json' ;
110+ const result = {
111+ request,
112+ response,
113+ } ;
114+
115+ if ( response . ok ) {
116+ const parseAs =
117+ ( opts . parseAs === 'auto'
118+ ? getParseAs ( response . headers . get ( 'Content-Type' ) )
119+ : opts . parseAs ) ?? 'json' ;
120+
121+ if ( response . status === 204 || response . headers . get ( 'Content-Length' ) === '0' ) {
122+ let emptyData : any ;
123+ switch ( parseAs ) {
124+ case 'arrayBuffer' :
125+ case 'blob' :
126+ case 'text' :
127+ emptyData = await response [ parseAs ] ( ) ;
128+ break ;
129+ case 'formData' :
130+ emptyData = new FormData ( ) ;
131+ break ;
132+ case 'stream' :
133+ emptyData = response . body ;
134+ break ;
135+ case 'json' :
136+ default :
137+ emptyData = { } ;
138+ break ;
139+ }
140+ return opts . responseStyle === 'data'
141+ ? emptyData
142+ : {
143+ data : emptyData ,
144+ ...result ,
145+ } ;
146+ }
140147
141- if ( response . status === 204 || response . headers . get ( 'Content-Length' ) === '0' ) {
142- let emptyData : any ;
148+ let data : any ;
143149 switch ( parseAs ) {
144150 case 'arrayBuffer' :
145151 case 'blob' :
152+ case 'formData' :
146153 case 'text' :
147- emptyData = await response [ parseAs ] ( ) ;
154+ data = await response [ parseAs ] ( ) ;
148155 break ;
149- case 'formData' :
150- emptyData = new FormData ( ) ;
156+ case 'json' : {
157+ // Some servers return 200 with no Content-Length and empty body.
158+ // response.json() would throw; read as text and parse if non-empty.
159+ const text = await response . text ( ) ;
160+ data = text ? JSON . parse ( text ) : { } ;
151161 break ;
162+ }
152163 case 'stream' :
153- emptyData = response . body ;
154- break ;
155- case 'json' :
156- default :
157- emptyData = { } ;
158- break ;
164+ return opts . responseStyle === 'data'
165+ ? response . body
166+ : {
167+ data : response . body ,
168+ ...result ,
169+ } ;
170+ }
171+
172+ if ( parseAs === 'json' ) {
173+ if ( opts . responseValidator ) {
174+ await opts . responseValidator ( data ) ;
175+ }
176+
177+ if ( opts . responseTransformer ) {
178+ data = await opts . responseTransformer ( data ) ;
179+ }
159180 }
181+
160182 return opts . responseStyle === 'data'
161- ? emptyData
183+ ? data
162184 : {
163- data : emptyData ,
185+ data,
164186 ...result ,
165187 } ;
166188 }
167189
168- let data : any ;
169- switch ( parseAs ) {
170- case 'arrayBuffer' :
171- case 'blob' :
172- case 'formData' :
173- case 'text' :
174- data = await response [ parseAs ] ( ) ;
175- break ;
176- case 'json' : {
177- // Some servers return 200 with no Content-Length and empty body.
178- // response.json() would throw; read as text and parse if non-empty.
179- const text = await response . text ( ) ;
180- data = text ? JSON . parse ( text ) : { } ;
181- break ;
182- }
183- case 'stream' :
184- return opts . responseStyle === 'data'
185- ? response . body
186- : {
187- data : response . body ,
188- ...result ,
189- } ;
190+ const textError = await response . text ( ) ;
191+ let jsonError : unknown ;
192+
193+ try {
194+ jsonError = JSON . parse ( textError ) ;
195+ } catch {
196+ // noop
190197 }
191198
192- if ( parseAs === 'json' ) {
193- if ( opts . responseValidator ) {
194- await opts . responseValidator ( data ) ;
195- }
199+ throw jsonError ?? textError ;
200+ } catch ( error ) {
201+ let finalError = error ;
196202
197- if ( opts . responseTransformer ) {
198- data = await opts . responseTransformer ( data ) ;
203+ for ( const fn of interceptors . error . fns ) {
204+ if ( fn ) {
205+ finalError = ( await fn ( error , response , request , options as any ) ) as unknown ;
199206 }
200207 }
201208
202- return opts . responseStyle === 'data'
203- ? data
204- : {
205- data,
206- ...result ,
207- } ;
208- }
209-
210- const textError = await response . text ( ) ;
211- let jsonError : unknown ;
212-
213- try {
214- jsonError = JSON . parse ( textError ) ;
215- } catch {
216- // noop
217- }
218-
219- const error = jsonError ?? textError ;
220- let finalError = error ;
209+ finalError = finalError || ( { } as unknown ) ;
221210
222- for ( const fn of interceptors . error . fns ) {
223- if ( fn ) {
224- finalError = ( await fn ( error , response , request , opts ) ) as string ;
211+ if ( throwOnError ) {
212+ throw finalError ;
225213 }
226- }
227-
228- finalError = finalError || ( { } as string ) ;
229214
230- if ( opts . throwOnError ) {
231- throw finalError ;
215+ // TODO: we probably want to return error and improve types
216+ return responseStyle === 'data'
217+ ? undefined
218+ : {
219+ error : finalError ,
220+ request,
221+ response : response as any ,
222+ } ;
232223 }
233-
234- // TODO: we probably want to return error and improve types
235- return opts . responseStyle === 'data'
236- ? undefined
237- : {
238- error : finalError ,
239- ...result ,
240- } ;
241224 } ;
242225
243226 const makeMethodFn = ( method : Uppercase < HttpMethod > ) => ( options : RequestOptions ) =>
0 commit comments