Skip to content

Commit f10aa37

Browse files
authored
feat: retry "Something went wrong" GraphQL error (#396)
1 parent 659b0f4 commit f10aa37

File tree

2 files changed

+140
-1
lines changed

2 files changed

+140
-1
lines changed

src/wrap-request.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// @ts-ignore
22
import Bottleneck from "bottleneck/light";
3+
import { RequestError } from "@octokit/request-error";
34

45
// @ts-ignore
56
export async function wrapRequest(state, request, options) {
@@ -18,5 +19,29 @@ export async function wrapRequest(state, request, options) {
1819
}
1920
});
2021

21-
return limiter.schedule(request, options);
22+
return limiter.schedule(
23+
requestWithGraphqlErrorHandling.bind(null, request),
24+
options
25+
);
26+
}
27+
28+
// @ts-ignore
29+
async function requestWithGraphqlErrorHandling(request, options) {
30+
const response = await request(request, options);
31+
32+
if (
33+
response.data.errors &&
34+
/Something went wrong while executing your query/.test(
35+
response.data.errors[0].message
36+
)
37+
) {
38+
// simulate 500 request error for retry handling
39+
const error = new RequestError(response.data.errors[0].message, 500, {
40+
request: options,
41+
response,
42+
});
43+
throw error;
44+
}
45+
46+
return response;
2247
}

test/retry.test.ts

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,120 @@ describe("Automatic Retries", function () {
265265

266266
expect(caught).toEqual(testStatuses.length);
267267
});
268+
269+
it('Should retry "Something went wrong" GraphQL error', async function () {
270+
const octokit = new TestOctokit();
271+
272+
const result = await octokit.graphql({
273+
query: `query {
274+
viewer {
275+
login
276+
}
277+
}`,
278+
request: {
279+
responses: [
280+
{
281+
status: 200,
282+
headers: {},
283+
data: {
284+
errors: [
285+
{
286+
message:
287+
// the `0000:0000:0000000:0000000:00000000` part is variable, it's the request ID provided by GitHub
288+
"Something went wrong while executing your query. Please include `0000:0000:0000000:0000000:00000000` when reporting this issue.",
289+
},
290+
],
291+
},
292+
},
293+
{
294+
status: 200,
295+
headers: {},
296+
data: {
297+
data: {
298+
viewer: {
299+
login: "gr2m",
300+
},
301+
},
302+
},
303+
},
304+
],
305+
retries: 1,
306+
},
307+
});
308+
309+
expect(result).toStrictEqual({
310+
viewer: {
311+
login: "gr2m",
312+
},
313+
});
314+
expect(octokit.__requestLog).toStrictEqual([
315+
"START POST /graphql",
316+
"END POST /graphql",
317+
"START POST /graphql",
318+
"END POST /graphql",
319+
]);
320+
321+
expect(
322+
octokit.__requestTimings[1] - octokit.__requestTimings[0]
323+
).toBeLessThan(20);
324+
});
325+
326+
it('Should not retry non-"Something went wrong" GraphQL errors', async function () {
327+
const octokit = new TestOctokit();
328+
329+
try {
330+
await octokit.graphql({
331+
query: `query {
332+
viewer {
333+
login
334+
}
335+
}`,
336+
request: {
337+
responses: [
338+
{
339+
status: 200,
340+
headers: {},
341+
data: {
342+
errors: [
343+
{
344+
message:
345+
"Something that cannot be fixed with a request retry",
346+
},
347+
],
348+
},
349+
},
350+
{
351+
status: 200,
352+
headers: {},
353+
data: {
354+
data: {
355+
viewer: {
356+
login: "gr2m",
357+
},
358+
},
359+
},
360+
},
361+
],
362+
retries: 1,
363+
},
364+
});
365+
throw new Error("Should not reach this point");
366+
} catch (error: any) {
367+
expect(error.name).toEqual("GraphqlResponseError");
368+
expect(error.message).toContain(
369+
"Something that cannot be fixed with a request retry"
370+
);
371+
}
372+
373+
expect(octokit.__requestLog).toStrictEqual([
374+
"START POST /graphql",
375+
"END POST /graphql",
376+
]);
377+
378+
expect(
379+
octokit.__requestTimings[1] - octokit.__requestTimings[0]
380+
).toBeLessThan(20);
381+
});
268382
});
269383

270384
describe("errorRequest", function () {

0 commit comments

Comments
 (0)