Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions apps/site/next-data/generators/supportersData.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { OPENCOLLECTIVE_MEMBERS_URL } from '#site/next.constants.mjs';
import { fetchWithRetry } from '#site/util/fetch';

/**
* Fetches supporters data from Open Collective API, filters active backers,
Expand All @@ -7,7 +8,7 @@ import { OPENCOLLECTIVE_MEMBERS_URL } from '#site/next.constants.mjs';
* @returns {Promise<Array<import('#site/types/supporters').OpenCollectiveSupporter>>} Array of supporters
*/
export default () =>
fetch(OPENCOLLECTIVE_MEMBERS_URL)
fetchWithRetry(OPENCOLLECTIVE_MEMBERS_URL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please please revert the change from async functions to Promises. THANK YOU

.then(response => response.json())
.then(payload =>
payload
Expand All @@ -20,5 +21,4 @@ export default () =>
profile,
source: 'opencollective',
}))
)
.catch(() => []);
);
12 changes: 7 additions & 5 deletions apps/site/next-data/generators/vulnerabilities.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { VULNERABILITIES_URL } from '#site/next.constants.mjs';
import { fetchWithRetry } from '#site/util/fetch';

const RANGE_REGEX = /([<>]=?)\s*(\d+)(?:\.(\d+))?/;
const V0_REGEX = /^0\.\d+(\.x)?$/;
const VER_REGEX = /^\d+\.x$/;

/**
* Fetches vulnerability data from the Node.js Security Working Group repository,
Expand All @@ -9,7 +12,7 @@ const RANGE_REGEX = /([<>]=?)\s*(\d+)(?:\.(\d+))?/;
* @returns {Promise<import('#site/types/vulnerabilities').GroupedVulnerabilities>} Grouped vulnerabilities
*/
export default () =>
fetch(VULNERABILITIES_URL)
fetchWithRetry(VULNERABILITIES_URL)
.then(response => response.json())
.then(payload => {
/** @type {Array<import('#site/types/vulnerabilities').RawVulnerability>} */
Expand All @@ -27,14 +30,14 @@ export default () =>
// Helper function to process version patterns
const processVersion = (version, vulnerability) => {
// Handle 0.X versions (pre-semver)
if (/^0\.\d+(\.x)?$/.test(version)) {
if (V0_REGEX.test(version)) {
addToGroup('0', vulnerability);

return;
}

// Handle simple major.x patterns (e.g., 12.x)
if (/^\d+\.x$/.test(version)) {
if (VER_REGEX.test(version)) {
const majorVersion = version.split('.')[0];

addToGroup(majorVersion, vulnerability);
Expand Down Expand Up @@ -79,5 +82,4 @@ export default () =>
}

return grouped;
})
.catch(() => ({}));
});
3 changes: 2 additions & 1 deletion apps/site/next.calendar.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
BASE_CALENDAR_URL,
SHARED_CALENDAR_KEY,
} from './next.calendar.constants.mjs';
import { fetchWithRetry } from './util/fetch';

/**
*
Expand Down Expand Up @@ -33,7 +34,7 @@ export const getCalendarEvents = async (calendarId = '', maxResults = 20) => {
calendarQueryUrl.searchParams.append(key, value)
);

return fetch(calendarQueryUrl)
return fetchWithRetry(calendarQueryUrl)
.then(response => response.json())
.then(calendar => calendar.items ?? []);
};
6 changes: 3 additions & 3 deletions apps/site/types/supporters.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export type Supporter = {
export type Supporter<T extends string> = {
name: string;
image: string;
url: string;
profile: string;
source: string;
source: T;
};

export type OpenCollectiveSupporter = Supporter & { source: 'opencollective' };
export type OpenCollectiveSupporter = Supporter<'opencollective'>;
24 changes: 24 additions & 0 deletions apps/site/util/fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { setTimeout } from 'node:timers/promises';

type RetryOptions = RequestInit & {
maxRetry: number;
delay: number;
};

export const fetchWithRetry = async (
url: string,
{ maxRetry = 3, delay = 100, ...options }: RetryOptions
) => {
for (let i = 1; i <= maxRetry; i++) {
try {
return fetch(url, options);
} catch (e) {
if (i === maxRetry) {
throw e;
}

await setTimeout(delay);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can add a backoff

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYM?

Copy link
Member

@araujogui araujogui Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A retry with backoff pattern

continue;
}
}
};
Loading