MCPcopy Create free account
hub / github.com/angular/dev-infra / invokeWithRetry

Function invokeWithRetry

ng-dev/utils/git/github.ts:33–68  ·  view source on GitHub ↗

Helper to invoke an async function with retries.

(fn: () => Promise<T>, retries = 3, delay = 1000)

Source from the content-addressed store, hash-verified

31
32/** Helper to invoke an async function with retries. */
33async function invokeWithRetry<T>(fn: () => Promise<T>, retries = 3, delay = 1000): Promise<T> {
34 let attempt = 0;
35 while (attempt < retries) {
36 try {
37 return await fn();
38 } catch (e) {
39 attempt++;
40 if (attempt >= retries) {
41 throw e;
42 }
43
44 // Do not retry valid 4xx Client Errors (especially 404 Not Found)
45 if (isGithubApiError(e) && e.status < 500) {
46 throw e;
47 }
48
49 // Do not retry permanent GraphQL errors
50 if (e instanceof GraphqlResponseError) {
51 if (!e.errors) {
52 throw e; // Missing errors, assume permanent or unknown
53 }
54 if (
55 e.errors.every((err) =>
56 ['NOT_FOUND', 'FORBIDDEN', 'BAD_USER_INPUT', 'UNAUTHENTICATED'].includes(err.type!),
57 )
58 ) {
59 throw e;
60 }
61 }
62
63 Log.warn(`GitHub API call failed (attempt ${attempt}/${retries}). Retrying in ${delay}ms...`);
64 await new Promise((resolve) => setTimeout(resolve, delay));
65 }
66 }
67 throw new Error('Unreachable');
68}
69
70/** Creates a proxy that intercepts function calls and applies retries. */
71function createRetryProxy<T extends object>(target: T): T {

Callers 2

applyFunction · 0.85
graphqlMethod · 0.85

Calls 2

isGithubApiErrorFunction · 0.85
setTimeoutFunction · 0.50

Tested by

no test coverage detected