Skip to content

Commit 9fdc9fa

Browse files
authored
metalsmith-link-checker: retry EAI_AGAIN errors automatically (#243)
1 parent a6d96b0 commit 9fdc9fa

4 files changed

Lines changed: 19 additions & 7 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/metalsmith-link-checker/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## v2.1.17 / 2025-11-27
4+
5+
- `EAI_AGAIN` errors are now retried automatically, regardless of of the `attempts` value.
6+
37
## v2.1.1 / 2024-02-18
48

59
- Don't validate `link[href][rel='preconnect']` links as they can 404 (e.g. `https://fonts.googleapis.com`).

packages/metalsmith-link-checker/index.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ const validUrl = async (
128128
return validUrlCache[link];
129129
}
130130

131-
const result = await new Promise<string | undefined>((resolve) => {
131+
const errorMessage = await new Promise<string | undefined>((resolve) => {
132132
debug('checking URL with %s: %s, attempt %i', method, link, attempt);
133133
const library = link.slice(0, 5) === 'https' ? https : http;
134134
const req = library.request(
@@ -169,21 +169,29 @@ const validUrl = async (
169169
});
170170

171171
// Re-attempt HEAD errors as GETs
172-
if (result && method === 'HEAD') {
172+
if (errorMessage && method === 'HEAD') {
173173
return validUrl(link, options, debug, attempt, 'GET');
174174
}
175175

176+
// Retry some failures automatically, even if retrying isn't specified
177+
if (errorMessage?.indexOf('EAI_AGAIN') !== -1 && attempt <= (options.attempts ?? 0) + 3) {
178+
await new Promise((resolve) => {
179+
setTimeout(resolve, Math.min(1000, 100 * 2 ** attempt));
180+
});
181+
return validUrl(link, options, debug, attempt + 1, method);
182+
}
183+
176184
// Retry failures if we haven't reached the retry limit
177-
if (result && attempt <= (options.attempts ?? 0)) {
185+
if (errorMessage && attempt <= (options.attempts ?? 0)) {
178186
await new Promise((resolve) => {
179187
setTimeout(resolve, Math.min(1000, 100 * 2 ** attempt));
180188
});
181189
return validUrl(link, options, debug, attempt + 1, method);
182190
}
183191

184192
// Otherwise, store the result and return
185-
validUrlCache[link] = result;
186-
return result;
193+
validUrlCache[link] = errorMessage;
194+
return errorMessage;
187195
};
188196

189197
/**

packages/metalsmith-link-checker/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "metalsmith-link-checker",
3-
"version": "2.1.16",
3+
"version": "2.1.17",
44
"description": "A Metalsmith plugin to check for broken links.",
55
"keywords": [
66
"metalsmith",

0 commit comments

Comments
 (0)