@@ -34,12 +34,17 @@ const setMiddleware = (middleware: typeof def.middleware) => {
34
34
def . middleware = middleware ;
35
35
} ;
36
36
37
- const api = async < T extends Config > ( config : T ) : Promise < Response & {
37
+ const api = async < T extends Config > ( config : T , retries = 0 ) : Promise < Response & {
38
38
config : Config ,
39
39
data : ResponseBody < T > ,
40
40
} > => {
41
41
const url = def . middleware ( config ) ;
42
- const { method, headers, timeout = 20000 } = config ;
42
+ const {
43
+ method,
44
+ headers,
45
+ timeout = 20000 ,
46
+ maxRetries = 3 ,
47
+ } = config ;
43
48
const abortController = new AbortController ( ) ;
44
49
const timer = setTimeout ( ( ) => abortController . abort ( ) , timeout ) ;
45
50
const response = await fetch ( url , {
@@ -55,10 +60,19 @@ const api = async <T extends Config>(config: T): Promise<Response & {
55
60
data : await response . json ( ) ,
56
61
} ;
57
62
}
63
+ const { status } = response ;
64
+ if ( maxRetries < retries && ( status === 429 || status >= 500 ) ) {
65
+ const retryAfter = response . headers . get ( 'retry-after' ) ;
66
+ return new Promise ( ( resolve , reject ) => {
67
+ setTimeout ( ( ) => {
68
+ api ( config , retries + 1 ) . then ( resolve ) . catch ( reject ) ;
69
+ } , ( retryAfter && parseInt ( retryAfter , 10 ) ) || 5000 ) ;
70
+ } ) ;
71
+ }
58
72
const error : any = new Error ( response . statusText ) ;
59
73
error . config = config ;
60
74
error . response = response ;
61
- error . statusCode = response . status ;
75
+ error . statusCode = status ;
62
76
throw error ;
63
77
} ;
64
78
0 commit comments