linkinator icon indicating copy to clipboard operation
linkinator copied to clipboard

Retry a gaxios request with new url

Open NathanDubord opened this issue 2 years ago • 1 comments

The way my site is built, some relative paths don't exist until we publish. I'm looking to retry failed HEAD requests with an absolute path.

Example: dist/index.html has 2 links in it. /link1 and link2. /link1 can be found no problem, returns a 200. /link2 returns a 404. I'd like to retry /link2 with an absolute path. http://mysite.com/link2.

Originally I was going to create a massive ignore list with all the relative paths that don't exist locally, but if any of those pages were to get deleted, I wouldn't be able to tell.

I could do the requests myself after, or write to a dummy file with all the new links and perform a new scan on just that file after?

Any ideas?

NathanDubord avatar Oct 02 '22 23:10 NathanDubord

My working solution, it's not the cleanest, but it's quick and it works.

import fs from 'fs';
import { LinkChecker } from 'linkinator';

const checkForBrokenLinks = async () => {
  const fullSiteChecker = new LinkChecker();
  const absolutePath = 'http://myabsolutepath.com';

  // Scan all index.html files in the /dist directory for broken url's.
  // .check() is an AsyncFunction, let's wait for results.
  const results = await fullSiteChecker.check({
    path: '**/index.html',
    timeout: 5000,
    linksToSkip: [
      '_nuxt',
      'node_modules',
    ],
  });

  const brokenLinks = results.links.filter((x) => x.state === 'BROKEN');
  const html = brokenLinks
    .map((brokenLink) => `<a href="${absolutePath}${brokenLink.url}"/>`)
    .join(' ');

  // inject all the broken links into a temporary html file.
  // We're going to re-run the scanner against the temporary file. Except this
  // time we're swapping the local path with the absolute path. This
  // is because the local references only work on prod.
  fs.writeFile('retry.html', html, () => console.log('Created retry.html'));
  const retryChecker = new LinkChecker();
  const retryResults = await retryChecker.check({
    path: 'retry.html',
    timeout: 5000,
  });

  console.log(`Scanned a total of ${results.links.length} links`);

  const broken = retryResults.links.filter((x) => x.state === 'BROKEN');
  console.log(`Found ${broken.length} broken links`);

  if (broken.length) {
    broken.forEach((brokenLink) =>
      console.log(
        `${brokenLink.status} - ${brokenLink.url.replace(absolutePath, '')}`,
      ),
    );
    process.exit(1);
  }
};

checkForBrokenLinks();

NathanDubord avatar Oct 04 '22 03:10 NathanDubord

Greetings! I can see how something like this is useful, but it's bespoke enough that I wouldn't want to try adding it to the tool. It's a great sign that you were able to piece this together using linkinator as an npm module, so I'm going to consider this a win!

JustinBeckwith avatar Dec 16 '22 04:12 JustinBeckwith