Skip to content

Commit d608b4b

Browse files
committed
feat: implement retrying on server errors
1 parent f5283c8 commit d608b4b

File tree

1 file changed

+90
-29
lines changed

1 file changed

+90
-29
lines changed

src/main.ts

Lines changed: 90 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,83 @@ import * as api from "./api.ts";
66
const DISTINCT_ID = uuid();
77
const WORKFLOW_FETCH_TIMEOUT_MS = 60 * 1000;
88
const WORKFLOW_JOB_STEPS_RETRY_MS = 5000;
9+
const WORKFLOW_JOB_STEPS_SERVER_ERROR_RETRY_MAX = 3;
10+
const WORKFLOW_JOB_STEPS_SERVER_ERROR_RETRY_MS = 500;
11+
12+
type Result = ResultFound | ResultNotFound;
13+
14+
interface ResultFound {
15+
found: true;
16+
value: {
17+
id: number;
18+
url: string;
19+
};
20+
}
21+
22+
interface ResultNotFound {
23+
found: false;
24+
}
25+
26+
/**
27+
* Attempt to read the distinct ID in the steps for each existing run ID.
28+
*/
29+
async function attemptToFindRunId(
30+
idRegex: RegExp,
31+
workflowRunIds: number[],
32+
): Promise<Result> {
33+
let currentWorkflowRunIndex = 0;
34+
let currentGetWorkflowRunJobStepsAttempt = 0;
35+
while (currentWorkflowRunIndex < workflowRunIds.length) {
36+
const id = workflowRunIds[currentWorkflowRunIndex];
37+
if (id === undefined) {
38+
break;
39+
}
40+
41+
try {
42+
const steps = await api.getWorkflowRunJobSteps(id);
43+
44+
for (const step of steps) {
45+
if (idRegex.test(step)) {
46+
const url = await api.getWorkflowRunUrl(id);
47+
return { found: true, value: { id, url } };
48+
}
49+
}
50+
} catch (error) {
51+
if (!(error instanceof Error)) {
52+
throw error;
53+
}
54+
55+
if (error.message === "Server Error") {
56+
if (
57+
currentGetWorkflowRunJobStepsAttempt <
58+
WORKFLOW_JOB_STEPS_SERVER_ERROR_RETRY_MAX
59+
) {
60+
currentGetWorkflowRunJobStepsAttempt++;
61+
62+
core.debug(
63+
"Encountered a Server Error while attempting to fetch steps, " +
64+
`retrying in ${WORKFLOW_JOB_STEPS_SERVER_ERROR_RETRY_MS}`,
65+
);
66+
await new Promise((resolve) =>
67+
setTimeout(resolve, WORKFLOW_JOB_STEPS_SERVER_ERROR_RETRY_MS),
68+
);
69+
70+
// Continue without increasing the current index to retry the same ID.
71+
continue;
72+
}
73+
} else if (error.message === "Not Found") {
74+
core.debug(`Could not identify ID in run: ${id}, continuing...`);
75+
} else {
76+
throw error;
77+
}
78+
}
79+
80+
currentGetWorkflowRunJobStepsAttempt = 0;
81+
currentWorkflowRunIndex++;
82+
}
83+
84+
return { found: false };
85+
}
986

1087
async function run(): Promise<void> {
1188
try {
@@ -53,35 +130,19 @@ async function run(): Promise<void> {
53130
`Attempting to get step names for Run IDs: [${workflowRunIds.join(", ")}]`,
54131
);
55132

56-
const idRegex = new RegExp(DISTINCT_ID);
57-
58-
/**
59-
* Attempt to read the distinct ID in the steps
60-
* for each existing run ID.
61-
*/
62-
for (const id of workflowRunIds) {
63-
try {
64-
const steps = await api.getWorkflowRunJobSteps(id);
65-
66-
for (const step of steps) {
67-
if (idRegex.test(step)) {
68-
const url = await api.getWorkflowRunUrl(id);
69-
core.info(
70-
"Successfully identified remote Run:\n" +
71-
` Run ID: ${id}\n` +
72-
` URL: ${url}`,
73-
);
74-
core.setOutput(ActionOutputs.runId, id);
75-
core.setOutput(ActionOutputs.runUrl, url);
76-
return;
77-
}
78-
}
79-
} catch (error) {
80-
if (error instanceof Error && error.message !== "Not Found") {
81-
throw error;
82-
}
83-
core.debug(`Could not identify ID in run: ${id}, continuing...`);
84-
}
133+
const idRegex = new RegExp(config.distinctId ?? DISTINCT_ID);
134+
135+
const result = await attemptToFindRunId(idRegex, workflowRunIds);
136+
if (result.found) {
137+
core.info(
138+
"Successfully identified remote Run:\n" +
139+
` Run ID: ${result.value.id}\n` +
140+
` URL: ${result.value.url}`,
141+
);
142+
core.setOutput(ActionOutputs.runId, result.value.id);
143+
core.setOutput(ActionOutputs.runUrl, result.value.url);
144+
core.debug(`Completed in ${Date.now() - startTime}ms`);
145+
return;
85146
}
86147

87148
core.info(

0 commit comments

Comments
 (0)