mirror of https://github.com/actions/toolkit
Add retry delay
parent
1ef26b2390
commit
de52c861c1
|
@ -20,7 +20,8 @@ async function handleResponse(
|
|||
if (response.statusCode >= 900) {
|
||||
throw Error('Test Error')
|
||||
} else if (response.statusCode >= 600) {
|
||||
const error: any = Error('Test Error with Status Code')
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const error = Error('Test Error with Status Code') as any
|
||||
error['statusCode'] = response.statusCode - 300
|
||||
throw error
|
||||
} else {
|
||||
|
@ -37,7 +38,9 @@ async function testRetryExpectingResult(
|
|||
const actualResult = await retry(
|
||||
'test',
|
||||
async () => handleResponse(responses.pop()),
|
||||
(response: TestResponse) => response.statusCode
|
||||
(response: TestResponse) => response.statusCode,
|
||||
2, // maxAttempts
|
||||
0 // delay
|
||||
)
|
||||
|
||||
expect(actualResult.result).toEqual(expectedResult)
|
||||
|
@ -54,12 +57,14 @@ async function testRetryConvertingErrorToResult(
|
|||
'test',
|
||||
async () => handleResponse(responses.pop()),
|
||||
(response: TestResponse) => response.statusCode,
|
||||
2,
|
||||
2, // maxAttempts
|
||||
0, // delay
|
||||
(e: Error) => {
|
||||
const error: any = e
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const error = e as any
|
||||
return {
|
||||
statusCode: error['statusCode'],
|
||||
result: error['result']
|
||||
result: error['result'] ?? null
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -77,7 +82,9 @@ async function testRetryExpectingError(
|
|||
retry(
|
||||
'test',
|
||||
async () => handleResponse(responses.pop()),
|
||||
(response: TestResponse) => response.statusCode
|
||||
(response: TestResponse) => response.statusCode,
|
||||
2, // maxAttempts,
|
||||
0 // delay
|
||||
)
|
||||
).rejects.toBeInstanceOf(Error)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ export enum CompressionMethod {
|
|||
Zstd = 'zstd'
|
||||
}
|
||||
|
||||
// The default delay in milliseconds between retry attempts.
|
||||
export const RetryDelay = 5000
|
||||
|
||||
// Socket timeout in milliseconds during download. If no traffic is received
|
||||
// over the socket during this period, the socket is destroyed and the download
|
||||
// is aborted.
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
IHttpClientResponse,
|
||||
ITypedResponse
|
||||
} from '@actions/http-client/interfaces'
|
||||
import {RetryDelay} from './constants'
|
||||
|
||||
export function isSuccessStatusCode(statusCode?: number): boolean {
|
||||
if (!statusCode) {
|
||||
|
@ -31,11 +32,16 @@ export function isRetryableStatusCode(statusCode?: number): boolean {
|
|||
return retryableStatusCodes.includes(statusCode)
|
||||
}
|
||||
|
||||
async function sleep(milliseconds: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, milliseconds))
|
||||
}
|
||||
|
||||
export async function retry<T>(
|
||||
name: string,
|
||||
method: () => Promise<T>,
|
||||
getStatusCode: (arg0: T) => number | undefined,
|
||||
maxAttempts = 2,
|
||||
delay = RetryDelay,
|
||||
onError: ((arg0: Error) => T | undefined) | undefined = undefined
|
||||
): Promise<T> {
|
||||
let errorMessage = ''
|
||||
|
@ -69,7 +75,7 @@ export async function retry<T>(
|
|||
isRetryable = isRetryableStatusCode(statusCode)
|
||||
errorMessage = `Cache service responded with ${statusCode}`
|
||||
}
|
||||
|
||||
|
||||
core.debug(
|
||||
`${name} - Attempt ${attempt} of ${maxAttempts} failed with error: ${errorMessage}`
|
||||
)
|
||||
|
@ -79,6 +85,7 @@ export async function retry<T>(
|
|||
break
|
||||
}
|
||||
|
||||
await sleep(delay)
|
||||
attempt++
|
||||
}
|
||||
|
||||
|
@ -95,11 +102,12 @@ export async function retryTypedResponse<T>(
|
|||
method,
|
||||
(response: ITypedResponse<T>) => response.statusCode,
|
||||
maxAttempts,
|
||||
RetryDelay,
|
||||
// If the error object contains the statusCode property, extract it and return
|
||||
// an ITypedResponse<T> so it can be processed by the retry logic. Explicitly
|
||||
// casting Error object to any to workaround missing property errors.
|
||||
// an ITypedResponse<T> so it can be processed by the retry logic.
|
||||
(e: Error) => {
|
||||
const error : any = e
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const error = e as any
|
||||
if (error['statusCode']) {
|
||||
return {
|
||||
statusCode: error['statusCode'],
|
||||
|
@ -122,6 +130,7 @@ export async function retryHttpClientResponse<T>(
|
|||
name,
|
||||
method,
|
||||
(response: IHttpClientResponse) => response.message.statusCode,
|
||||
maxAttempts
|
||||
maxAttempts,
|
||||
RetryDelay
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue