diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 94e8d18..3699462 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,6 +32,14 @@ jobs: "sudo bastille cmd node cat /usr/local/indiekit/content/.indiekit/homepage.json" \ > content/.indiekit/homepage.json + - name: Cache Eleventy fetch cache + uses: actions/cache@v4 + with: + path: .cache + key: eleventy-fetch-${{ runner.os }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + eleventy-fetch-${{ runner.os }}- + - name: Build CSS run: npm run build:css diff --git a/lib/unfurl-shortcode.js b/lib/unfurl-shortcode.js index 7494a5b..ff8ba93 100644 --- a/lib/unfurl-shortcode.js +++ b/lib/unfurl-shortcode.js @@ -132,10 +132,15 @@ export async function prefetchUrl(url) { const metadata = await throttled(async () => { try { - return await unfurl(url, { - timeout: 20000, - headers: { "User-Agent": USER_AGENT }, - }); + // Hard outer deadline guards against TCP-level hangs that bypass unfurl's + // own timeout (which only covers HTTP read, not connection establishment). + const deadline = new Promise((_, reject) => + setTimeout(() => reject(new Error("hard deadline 22s")), 22000) + ); + return await Promise.race([ + unfurl(url, { timeout: 18000, headers: { "User-Agent": USER_AGENT } }), + deadline, + ]); } catch (err) { console.warn(`[unfurl] Failed to fetch ${url}: ${err.message}`); return null;