Skip to content

Commit 895cce7

Browse files
committed
fix: add retry mechanism to fetch.js to handle rate limiting
Signed-off-by: Amr ElSayyad <[email protected]>
1 parent d3fdcee commit 895cce7

File tree

1 file changed

+78
-46
lines changed

1 file changed

+78
-46
lines changed

fetch.js

Lines changed: 78 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
fs = require("fs");
1+
const feed2json = require("feed2json");
2+
const fs = require("fs");
23
const https = require("https");
3-
process = require("process");
4+
const process = require("process");
45
require("dotenv").config();
56

67
const GITHUB_TOKEN = process.env.REACT_APP_GITHUB_TOKEN;
@@ -16,6 +17,57 @@ const ERR = {
1617
requestFailedMedium:
1718
"The request to Medium didn't succeed. Check if Medium username in your .env file is correct."
1819
};
20+
21+
async function fetchWithRetry(options, data, retries = 5, delay = 5000) {
22+
for (let i = 0; i < retries; i++) {
23+
try {
24+
return await new Promise((resolve, reject) => {
25+
const req = https.request(options, res => {
26+
let responseData = "";
27+
28+
res.on("data", d => {
29+
responseData += d;
30+
});
31+
32+
res.on("end", () => {
33+
if (res.statusCode === 200) {
34+
resolve(responseData);
35+
} else if (res.statusCode === 429 && i < retries - 1) {
36+
console.log(`Rate limited. Retrying in ${delay}ms...`);
37+
setTimeout(
38+
() =>
39+
resolve(fetchWithRetry(options, data, retries - 1, delay)),
40+
delay
41+
);
42+
} else {
43+
reject(
44+
new Error(
45+
`${options.path} request failed with status code: ${res.statusCode}`
46+
)
47+
);
48+
}
49+
});
50+
});
51+
52+
req.on("error", error => {
53+
reject(error);
54+
});
55+
56+
if (data) {
57+
req.write(data);
58+
}
59+
req.end();
60+
});
61+
} catch (error) {
62+
if (i === retries - 1) {
63+
throw error;
64+
}
65+
console.log(`Error fetching data. Retrying in ${delay}ms...`);
66+
await new Promise(resolve => setTimeout(resolve, delay));
67+
}
68+
}
69+
}
70+
1971
if (USE_GITHUB_DATA === "true") {
2072
if (GITHUB_USERNAME === undefined) {
2173
throw new Error(ERR.noUserName);
@@ -67,64 +119,44 @@ if (USE_GITHUB_DATA === "true") {
67119
}
68120
};
69121

70-
const req = https.request(default_options, res => {
71-
let data = "";
72-
73-
console.log(`statusCode: ${res.statusCode}`);
74-
if (res.statusCode !== 200) {
75-
throw new Error(ERR.requestFailed);
76-
}
77-
78-
res.on("data", d => {
79-
data += d;
80-
});
81-
res.on("end", () => {
82-
fs.writeFile("./public/profile.json", data, function (err) {
122+
fetchWithRetry(default_options, data)
123+
.then(responseData => {
124+
fs.writeFile("./public/profile.json", responseData, function (err) {
83125
if (err) return console.log(err);
84126
console.log("saved file to public/profile.json");
85127
});
128+
})
129+
.catch(error => {
130+
console.error("Error:", error);
86131
});
87-
});
88-
89-
req.on("error", error => {
90-
throw error;
91-
});
92-
93-
req.write(data);
94-
req.end();
95132
}
96133

97134
if (MEDIUM_USERNAME !== undefined) {
98135
console.log(`Fetching Medium blogs data for ${MEDIUM_USERNAME}`);
136+
const url = `https://medium.com/feed/@${MEDIUM_USERNAME}`;
99137
const options = {
100-
hostname: "api.rss2json.com",
101-
path: `/v1/api.json?rss_url=https://medium.com/feed/@${MEDIUM_USERNAME}`,
138+
hostname: "medium.com",
139+
path: `/feed/@${MEDIUM_USERNAME}`,
102140
port: 443,
103141
method: "GET"
104142
};
105143

106-
const req = https.request(options, res => {
107-
let mediumData = "";
108-
109-
console.log(`statusCode: ${res.statusCode}`);
110-
if (res.statusCode !== 200) {
111-
throw new Error(ERR.requestMediumFailed);
112-
}
144+
fetchWithRetry(options)
145+
.then(responseData => {
146+
feed2json.fromString(responseData, url, {}, (err, json) => {
147+
if (err) {
148+
console.error("Error converting feed to JSON:", err);
149+
return;
150+
}
113151

114-
res.on("data", d => {
115-
mediumData += d;
116-
});
117-
res.on("end", () => {
118-
fs.writeFile("./public/blogs.json", mediumData, function (err) {
119-
if (err) return console.log(err);
120-
console.log("saved file to public/blogs.json");
152+
const mediumData = JSON.stringify(json, null, 2);
153+
fs.writeFile("./public/blogs.json", mediumData, function (err) {
154+
if (err) return console.error(err);
155+
console.log("Saved file to public/blogs.json");
156+
});
121157
});
158+
})
159+
.catch(error => {
160+
console.error("Error:", error);
122161
});
123-
});
124-
125-
req.on("error", error => {
126-
throw error;
127-
});
128-
129-
req.end();
130162
}

0 commit comments

Comments
 (0)