Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(v2): improve broken links error message #3569

Merged
merged 2 commits into from
Oct 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,64 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`brokenLinks getBrokenLinksErrorMessage 1`] = `
"Broken links found!
"Docusaurus found broken links!

- Page path = /docs/mySourcePage:
-> link to ./myBrokenLink (resolved as: /docs/myBrokenLink)
-> link to ../otherBrokenLink (resolved as: /otherBrokenLink)
Please check the pages of your site in the list bellow, and make sure you don't reference any path that does not exist.
Note: it's possible to ignore broken links with the 'onBrokenLinks' Docusaurus configuration, and let the build pass.

Exhaustive list of all broken links found:

- Page path = /otherSourcePage:
-> link to /badLink
- On source page path = /docs/mySourcePage:
-> linking to ./myBrokenLink (resolved as: /docs/myBrokenLink)
-> linking to ../otherBrokenLink (resolved as: /otherBrokenLink)

- On source page path = /otherSourcePage:
-> linking to /badLink
"
`;

exports[`brokenLinks getBrokenLinksErrorMessage with potential layout broken links 1`] = `
"Docusaurus found broken links!

Please check the pages of your site in the list bellow, and make sure you don't reference any path that does not exist.
Note: it's possible to ignore broken links with the 'onBrokenLinks' Docusaurus configuration, and let the build pass.

It looks like some of the broken links we found appear in many pages of your site.
Maybe those broken links appear on all pages through your site layout?
We recommend that you check your theme configuration for such links (particularly, theme navbar and footer).
Frequent broken links are linking to:
- ./myBrokenLinkFrequent1
- ./myBrokenLinkFrequent2


Exhaustive list of all broken links found:

- On source page path = /docs/page1:
-> linking to ./myBrokenLinkFrequent1 (resolved as: /docs/myBrokenLinkFrequent1)
-> linking to ./myBrokenLinkFrequent2 (resolved as: /docs/myBrokenLinkFrequent2)

- On source page path = /docs/page2:
-> linking to ./myBrokenLinkFrequent1 (resolved as: /docs/myBrokenLinkFrequent1)
-> linking to ./myBrokenLinkFrequent2 (resolved as: /docs/myBrokenLinkFrequent2)
-> linking to ./myBrokenLinkInfrequent1 (resolved as: /docs/myBrokenLinkInfrequent1)
-> linking to ./myBrokenLinkInfrequent2 (resolved as: /docs/myBrokenLinkInfrequent2)

- On source page path = /docs/page3:
-> linking to ./myBrokenLinkFrequent1 (resolved as: /docs/myBrokenLinkFrequent1)
-> linking to ./myBrokenLinkFrequent2 (resolved as: /docs/myBrokenLinkFrequent2)

- On source page path = /docs/page4:
-> linking to ./myBrokenLinkFrequent1 (resolved as: /docs/myBrokenLinkFrequent1)
-> linking to ./myBrokenLinkFrequent2 (resolved as: /docs/myBrokenLinkFrequent2)
-> linking to ./myBrokenLinkInfrequent1 (resolved as: /docs/myBrokenLinkInfrequent1)
-> linking to ./myBrokenLinkInfrequent2 (resolved as: /docs/myBrokenLinkInfrequent2)

- On source page path = /docs/page5:
-> linking to ./myBrokenLinkFrequent1 (resolved as: /docs/myBrokenLinkFrequent1)
-> linking to ./myBrokenLinkFrequent2 (resolved as: /docs/myBrokenLinkFrequent2)

- On source page path = /docs/page6:
-> linking to ./myBrokenLinkFrequent1 (resolved as: /docs/myBrokenLinkFrequent1)
-> linking to ./myBrokenLinkFrequent2 (resolved as: /docs/myBrokenLinkFrequent2)
"
`;
33 changes: 33 additions & 0 deletions packages/docusaurus/src/server/__tests__/brokenLinks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,39 @@ describe('brokenLinks', () => {
expect(message).toMatchSnapshot();
});

test('getBrokenLinksErrorMessage with potential layout broken links', async () => {
const frequentLink = [
{
link: './myBrokenLinkFrequent1',
resolvedLink: '/docs/myBrokenLinkFrequent1',
},
{
link: './myBrokenLinkFrequent2',
resolvedLink: '/docs/myBrokenLinkFrequent2',
},
];
const infrequentLink = [
{
link: './myBrokenLinkInfrequent1',
resolvedLink: '/docs/myBrokenLinkInfrequent1',
},
{
link: './myBrokenLinkInfrequent2',
resolvedLink: '/docs/myBrokenLinkInfrequent2',
},
];

const message = getBrokenLinksErrorMessage({
'/docs/page1': [...frequentLink],
'/docs/page2': [...frequentLink, ...infrequentLink],
'/docs/page3': [...frequentLink],
'/docs/page4': [...frequentLink, ...infrequentLink],
'/docs/page5': [...frequentLink],
'/docs/page6': [...frequentLink],
});
expect(message).toMatchSnapshot();
});

test('getAllBrokenLinks', async () => {
const routes: RouteConfig[] = [
{
Expand Down
44 changes: 37 additions & 7 deletions packages/docusaurus/src/server/brokenLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import {matchRoutes, RouteConfig as RRRouteConfig} from 'react-router-config';
import resolvePathname from 'resolve-pathname';
import fs from 'fs-extra';
import {mapValues, pickBy} from 'lodash';
import {mapValues, pickBy, flatten, countBy} from 'lodash';
import {RouteConfig, ReportingSeverity} from '@docusaurus/types';
import {removePrefix, removeSuffix} from '@docusaurus/utils';
import {getAllFinalRoutes, reportMessage} from './utils';
Expand Down Expand Up @@ -99,14 +99,45 @@ export function getBrokenLinksErrorMessage(
pagePath: string,
brokenLinks: BrokenLink[],
): string {
return `\n\n- Page path = ${pagePath}:\n -> link to ${brokenLinks
return `\n- On source page path = ${pagePath}:\n -> linking to ${brokenLinks
.map(brokenLinkMessage)
.join('\n -> link to ')}`;
.join('\n -> linking to ')}`;
}

// If there's a broken link appearing very often, it is probably a broken link on the layout!
// Add an additional message in such case to help user figure this out.
// see https://github.com/facebook/docusaurus/issues/3567#issuecomment-706973805
function getLayoutBrokenLinksHelpMessage() {
const flatList = flatten(
Object.entries(allBrokenLinks).map(([pagePage, brokenLinks]) =>
brokenLinks.map((brokenLink) => ({pagePage, brokenLink})),
),
);

const countedBrokenLinks = countBy(
flatList,
(item) => item.brokenLink.link,
);

const FrequencyThreshold = 5; // Is this a good value?
const frequentLinks = Object.entries(countedBrokenLinks)
.filter(([, count]) => count >= FrequencyThreshold)
.map(([link]) => link);

if (frequentLinks.length === 0) {
return '';
}

return `\n\nIt looks like some of the broken links we found appear in many pages of your site.\nMaybe those broken links appear on all pages through your site layout?\nWe recommend that you check your theme configuration for such links (particularly, theme navbar and footer).\nFrequent broken links are linking to: \n- ${frequentLinks.join(
`\n- `,
)}\n`;
}

return (
`Broken links found!` +
`${Object.entries(allBrokenLinks)
`Docusaurus found broken links!\n\nPlease check the pages of your site in the list bellow, and make sure you don't reference any path that does not exist.\nNote: it's possible to ignore broken links with the 'onBrokenLinks' Docusaurus configuration, and let the build pass.${getLayoutBrokenLinksHelpMessage()}` +
`\n\nExhaustive list of all broken links found:\n${Object.entries(
allBrokenLinks,
)
.map(([pagePath, brokenLinks]) =>
pageBrokenLinksMessage(pagePath, brokenLinks),
)
Expand Down Expand Up @@ -191,7 +222,6 @@ export async function handleBrokenLinks({

const errorMessage = getBrokenLinksErrorMessage(allBrokenLinks);
if (errorMessage) {
const finalMessage = `${errorMessage}\nNote: it's possible to ignore broken links with the 'onBrokenLinks' Docusaurus configuration.\n\n`;
reportMessage(finalMessage, onBrokenLinks);
reportMessage(errorMessage, onBrokenLinks);
}
}