* Add retry functionality to the client
(client: Client, maxRetries: number, retryDelay: number)
| 114 | * Add retry functionality to the client |
| 115 | */ |
| 116 | function addRetryFunctionality(client: Client, maxRetries: number, retryDelay: number): void { |
| 117 | // Store the original request method |
| 118 | const originalRequest = client.request; |
| 119 | |
| 120 | // Override the request method with retry functionality |
| 121 | const originalRequestTyped = originalRequest as <T>(config: AxiosRequestConfig) => Promise<T>; |
| 122 | |
| 123 | client.request = async function retryableRequest<T>(config: AxiosRequestConfig): Promise<T> { |
| 124 | async function attempt(retryCount: number): Promise<T> { |
| 125 | try { |
| 126 | return await originalRequestTyped<T>(config); |
| 127 | } catch (error) { |
| 128 | // If we've exhausted all retries, handle the error and throw |
| 129 | if (retryCount >= maxRetries) { |
| 130 | handleApiError(error); |
| 131 | } |
| 132 | |
| 133 | // Only retry on specific conditions |
| 134 | if (axios.isAxiosError(error)) { |
| 135 | const status = error.response?.status; |
| 136 | const isRetryableError = shouldRetryError(error, status); |
| 137 | |
| 138 | if (isRetryableError) { |
| 139 | const currentAttempt = retryCount + 1; |
| 140 | const delay = calculateDelay(retryDelay, retryCount); |
| 141 | |
| 142 | logger.retry(null, currentAttempt, maxRetries, delay); |
| 143 | await new Promise(resolve => setTimeout(resolve, delay)); |
| 144 | return attempt(retryCount + 1); |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | // Not retryable, handle error and throw |
| 149 | handleApiError(error); |
| 150 | } |
| 151 | } |
| 152 | |
| 153 | return attempt(0); |
| 154 | }; |
| 155 | } |
| 156 | |
| 157 | /** |
| 158 | * Determines if an error should be retried |
no test coverage detected