Skip to content

Commit 76dbd8f

Browse files
committed
Reduce 429 error responses when checking links
- set concurrency to 1 - retry 429 responses with retry-after header - set bearer token for GitHub links
1 parent ffcb10a commit 76dbd8f

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

.github/workflows/docs_test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ jobs:
3434
working-directory: docs/v2
3535
run: ./render.sh
3636
- name: Run docs tests
37+
env:
38+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3739
run: |
3840
bundle config set --local without 'development'
3941
bundle install

docs/v3/gulpfile.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import gulp from 'gulp';
44
import express from 'express';
55
import { glob } from 'glob';
66
import { LinkChecker } from 'linkinator';
7+
import { instance as gaxios } from 'gaxios';
78

89
import * as cheerio from 'cheerio';
910

@@ -85,17 +86,68 @@ async function checkPathAndExit(path, options, done) {
8586

8687
const url = 'http://localhost:8001/';
8788

89+
const githubToken = process.env.GITHUB_TOKEN;
90+
8891
const config = {
8992
path: url,
9093
linksToSkip: options.linksToSkip || [],
9194
recurse: options.recurse,
9295
silent: options.silent,
9396
markdown: options.markdown,
97+
concurrency: 1,
98+
retry: true,
99+
beforeRequest: (url, options) => {
100+
// add the bearer token for GitHub links
101+
if (githubToken && url.host.endsWith('github.com')) {
102+
options.headers = {
103+
...(options.headers || {}),
104+
authorization: `Bearer ${githubToken}`,
105+
};
106+
}
107+
return options;
108+
},
94109
};
95110

96111
try {
112+
gaxios.interceptors.response.add({
113+
// onFulfilled
114+
resolved: (response) => {
115+
if (response.config.url?.includes('github.com')) {
116+
console.log(
117+
`→ [${response.status}] ${response.config.url}\n`,
118+
response.headers
119+
);
120+
}
121+
return response;
122+
},
123+
// onRejected (catches 4xx/5xx too)
124+
rejected: (error) => {
125+
const resp = error.response;
126+
if (resp?.status === 429 && resp.config.url.includes('github.com')) {
127+
console.error(
128+
`→ 429 on ${resp.config.url}\n`,
129+
'Request headers:', resp.config.headers,
130+
'\nResponse headers:', resp.headers
131+
);
132+
}
133+
return Promise.reject(error);
134+
},
135+
});
136+
97137
const checker = new LinkChecker();
98138

139+
// Fires after *each* link is checked
140+
checker.on('link', (result) => {
141+
if (result.state === 'BROKEN') {
142+
// failureDetails is an array; each entry has `.headers`
143+
const detail = result.failureDetails[0];
144+
console.log(
145+
`[${result.status}] ${result.url}`,
146+
'\n→ headers:', detail.headers
147+
);
148+
}
149+
});
150+
99151
if (path === '../v2') {
100152
const htmlFiles = await glob(path + '/**/*.html');
101153
let allResults = { links: [] };

0 commit comments

Comments
 (0)