Skip to content

Commit ed37311

Browse files
fix(benchmark): handle non-JSON workflow polling responses (#7662)
* fix(benchmark): handle non-JSON workflow polling responses Co-authored-by: Thomas Watson <[email protected]>
1 parent 0a08693 commit ed37311

File tree

1 file changed

+56
-3
lines changed

1 file changed

+56
-3
lines changed

benchmark/e2e-test-optimization/benchmark-run.js

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,36 @@ const GET_WORKFLOWS_URL = `${API_REPOSITORY_URL}/actions/runs`
1111

1212
const MAX_ATTEMPTS = 30 * 60 / 5 // 30 minutes, polling every 5 seconds = 360 attempts
1313

14+
const getResponsePreview = (body) => {
15+
return body.replace(/\s+/g, ' ').slice(0, 200)
16+
}
17+
18+
const parseGitHubJsonResponse = ({ body, endpoint, res }) => {
19+
const statusCode = res.statusCode || 0
20+
if (statusCode < 200 || statusCode >= 300) {
21+
throw new Error(
22+
`GitHub API ${endpoint} returned status ${statusCode}. Body preview: ${getResponsePreview(body)}`
23+
)
24+
}
25+
26+
const contentType = String(res.headers['content-type'] || '')
27+
if (!contentType.includes('application/json')) {
28+
throw new Error(
29+
`GitHub API ${endpoint} returned unexpected content-type "${contentType}". Body preview: ${
30+
getResponsePreview(body)
31+
}`
32+
)
33+
}
34+
35+
try {
36+
return JSON.parse(body)
37+
} catch (e) {
38+
throw new Error(
39+
`GitHub API ${endpoint} returned invalid JSON. Body preview: ${getResponsePreview(body)}`
40+
)
41+
}
42+
}
43+
1444
function getBranchUnderTest () {
1545
/**
1646
* GITHUB_HEAD_REF is only set for `pull_request` events
@@ -72,7 +102,15 @@ const getWorkflowRunsInProgress = () => {
72102
response += chunk
73103
})
74104
res.on('end', () => {
75-
resolve(JSON.parse(response))
105+
try {
106+
resolve(parseGitHubJsonResponse({
107+
body: response,
108+
endpoint: `${GET_WORKFLOWS_URL}?event=workflow_dispatch`,
109+
res,
110+
}))
111+
} catch (e) {
112+
reject(e)
113+
}
76114
})
77115
})
78116
request.on('error', err => {
@@ -99,7 +137,15 @@ const getCurrentWorkflowJobs = (runId) => {
99137
body += chunk
100138
})
101139
res.on('end', () => {
102-
resolve(JSON.parse(body))
140+
try {
141+
resolve(parseGitHubJsonResponse({
142+
body,
143+
endpoint: `${GET_WORKFLOWS_URL}/${runId}/jobs`,
144+
res,
145+
}))
146+
} catch (e) {
147+
reject(e)
148+
}
103149
})
104150
})
105151
request.on('error', err => {
@@ -142,7 +188,14 @@ async function main () {
142188

143189
// Poll every 5 seconds until we have a finished status, up to 30 minutes
144190
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
145-
const currentWorkflow = await getCurrentWorkflowJobs(runId)
191+
let currentWorkflow
192+
try {
193+
currentWorkflow = await getCurrentWorkflowJobs(runId)
194+
} catch (e) {
195+
console.error('Workflow check failed (%s). Retry in 5 seconds.', e.message)
196+
await setTimeout(5000)
197+
continue
198+
}
146199
const { jobs } = currentWorkflow
147200
if (!jobs) {
148201
console.error('Workflow check returned unknown object %o. Retry in 5 seconds.', currentWorkflow)

0 commit comments

Comments
 (0)