@@ -126,6 +126,7 @@ export const createClient = (config: Config = {}): Client => {
126126
127127 let request : Request | undefined ;
128128 let response : KyResponse | undefined ;
129+ let errorInterceptorsInvoked = false ;
129130
130131 try {
131132 const { opts, url } = await beforeRequest ( options ) ;
@@ -177,6 +178,10 @@ export const createClient = (config: Config = {}): Client => {
177178 }
178179 }
179180
181+ // parseErrorResponse will run error interceptors, and re-throw when
182+ // throwOnError is true, which bubbles already intercepted error to
183+ // outer catch. With this flag, we can avoid outer catch running interceptors again
184+ errorInterceptorsInvoked = true ;
180185 return parseErrorResponse ( response , request , opts , interceptors ) ;
181186 }
182187
@@ -269,17 +274,31 @@ export const createClient = (config: Config = {}): Client => {
269274 } ;
270275 }
271276
277+ // parseErrorResponse will run error interceptors, and re-throw when
278+ // throwOnError is true, which bubbles already intercepted error to
279+ // outer catch. With this flag, we can avoid outer catch running interceptors again
280+ errorInterceptorsInvoked = true ;
272281 return parseErrorResponse ( response , request , opts , interceptors ) ;
273282 } catch ( error ) {
274283 let finalError = error ;
275284
276- for ( const fn of interceptors . error . fns ) {
277- if ( fn ) {
278- finalError = ( await fn ( finalError , response , request , options as any ) ) as string ;
285+ // error may already be processed by parseErrorResponse, in this case
286+ // we can skip running interceptors again
287+ if ( ! errorInterceptorsInvoked ) {
288+ // parseErrorResponse already ran interceptors and threw (throwOnError=true); just re-throw
289+ for ( const fn of interceptors . error . fns ) {
290+ if ( fn ) {
291+ finalError = ( await fn (
292+ finalError ,
293+ response as any ,
294+ request as any ,
295+ options as any ,
296+ ) ) as string ;
297+ }
279298 }
280- }
281299
282- finalError = finalError || ( { } as string ) ;
300+ finalError = finalError || ( { } as string ) ;
301+ }
283302
284303 if ( throwOnError ) {
285304 throw finalError ;
0 commit comments