-
Notifications
You must be signed in to change notification settings - Fork 213
Expand file tree
/
Copy pathutils.ts
More file actions
70 lines (63 loc) · 2.37 KB
/
utils.ts
File metadata and controls
70 lines (63 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { pause } from '@redocly/openapi-core';
import { DeploymentError } from '../utils.js';
import { ReuniteApiError } from '../api/index.js';
import { exitWithError } from '../../utils/error.js';
/**
* This function retries an operation until a condition is met or a timeout is exceeded.
* If the condition is not met within the timeout, an error is thrown.
* @operation The operation to retry.
* @condition The condition to check after each operation result. Return false to continue retrying. Return true to stop retrying.
* If not provided, the first result will be returned.
* @param onConditionNotMet Will be called with the last result right after checking condition and before timeout and retrying.
* @param onRetry Will be called right before retrying operation with the last result before retrying.
* @param startTime The start time of the operation. Default is the current time.
* @param retryTimeoutMs The maximum time to retry the operation. Default is 10 minutes.
* @param retryIntervalMs The interval between retries. Default is 5 seconds.
*/
export async function retryUntilConditionMet<T>({
operation,
condition,
onConditionNotMet,
onRetry,
startTime = Date.now(),
retryTimeoutMs = 600000, // 10 min
retryIntervalMs = 5000, // 5 sec
}: {
operation: () => Promise<T>;
condition?: ((result: T) => boolean) | null;
onConditionNotMet?: (lastResult: T) => void;
onRetry?: (lastResult: T) => void | Promise<void>;
startTime?: number;
retryTimeoutMs?: number;
retryIntervalMs?: number;
}): Promise<T> {
async function attempt(): Promise<T> {
const result = await operation();
if (!condition) {
return result;
}
if (condition(result)) {
return result;
} else if (Date.now() - startTime > retryTimeoutMs) {
throw new Error('Timeout exceeded.');
} else {
onConditionNotMet?.(result);
await pause(retryIntervalMs);
await onRetry?.(result);
return attempt();
}
}
return attempt();
}
export function handleReuniteError(
message: string,
error: ReuniteApiError | DeploymentError | Error
) {
if (error instanceof DeploymentError) {
return exitWithError(error.message);
}
if (error instanceof ReuniteApiError) {
return exitWithError(`${message} Reason: ${error.message} (status: ${error.status})\n`);
}
return exitWithError(`${message} Reason: ${error.message}\n`);
}