@@ -124,6 +124,7 @@ export const createClient = (config: Config = {}): Client => {
124124
125125 let request : Request | undefined ;
126126 let response : KyResponse | undefined ;
127+ let errorInterceptorsInvoked = false ;
127128
128129 try {
129130 const { opts, url } = await beforeRequest ( options ) ;
@@ -175,6 +176,10 @@ export const createClient = (config: Config = {}): Client => {
175176 }
176177 }
177178
179+ // parseErrorResponse will run error interceptors, and re-throw when
180+ // throwOnError is true, which bubbles already intercepted error to
181+ // outer catch. With this flag, we can avoid outer catch running interceptors again
182+ errorInterceptorsInvoked = true ;
178183 return parseErrorResponse ( response , request , opts , interceptors ) ;
179184 }
180185
@@ -267,17 +272,31 @@ export const createClient = (config: Config = {}): Client => {
267272 } ;
268273 }
269274
275+ // parseErrorResponse will run error interceptors, and re-throw when
276+ // throwOnError is true, which bubbles already intercepted error to
277+ // outer catch. With this flag, we can avoid outer catch running interceptors again
278+ errorInterceptorsInvoked = true ;
270279 return parseErrorResponse ( response , request , opts , interceptors ) ;
271280 } catch ( error ) {
272281 let finalError = error ;
273282
274- for ( const fn of interceptors . error . fns ) {
275- if ( fn ) {
276- finalError = ( await fn ( finalError , response , request , options as any ) ) as string ;
283+ // error may already be processed by parseErrorResponse, in this case
284+ // we can skip running interceptors again
285+ if ( ! errorInterceptorsInvoked ) {
286+ // parseErrorResponse already ran interceptors and threw (throwOnError=true); just re-throw
287+ for ( const fn of interceptors . error . fns ) {
288+ if ( fn ) {
289+ finalError = ( await fn (
290+ finalError ,
291+ response as any ,
292+ request as any ,
293+ options as any ,
294+ ) ) as string ;
295+ }
277296 }
278- }
279297
280- finalError = finalError || ( { } as string ) ;
298+ finalError = finalError || ( { } as string ) ;
299+ }
281300
282301 if ( throwOnError ) {
283302 throw finalError ;
0 commit comments