From 2682f167a1776de2f0c8085b591b06319a2aac7d Mon Sep 17 00:00:00 2001 From: Admir Skomorac Date: Mon, 29 Dec 2025 16:24:03 +0100 Subject: [PATCH 1/2] fix: handle non-array response from /locations and format with prettier --- lib.js | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/lib.js b/lib.js index 4a9cc2c..cc15db7 100644 --- a/lib.js +++ b/lib.js @@ -40,7 +40,7 @@ async function get(hostname, path) { req.on("error", (err) => { reject(err); }); - }, + } ); req.end(); @@ -48,7 +48,18 @@ async function get(hostname, path) { } async function fetchServerLocationData() { - const res = JSON.parse(await get("speed.cloudflare.com", "/locations")); + const responseData = await get("speed.cloudflare.com", "/locations"); + let res; + + try { + res = JSON.parse(responseData); + } catch (e) { + return {}; + } + + if (!Array.isArray(res)) { + return {}; + } return res.reduce((data, { iata, city }) => { // Bypass prettier "no-assign-param" rules @@ -103,8 +114,7 @@ function request(options, data = "") { res.on("data", () => {}); res.on("end", () => { ended = performance.now(); - resolve({started, dnsLookup, tcpHandshake, sslHandshake, ttfb, ended, - serverTiming: parseFloat(res.headers["server-timing"].slice(22))}); + resolve({ started, dnsLookup, tcpHandshake, sslHandshake, ttfb, ended, serverTiming: parseFloat(res.headers["server-timing"].slice(22)) }); }); }); @@ -168,7 +178,7 @@ async function measureLatency() { }, (error) => { console.error(`Error: ${error}`); - }, + } ); } @@ -186,7 +196,7 @@ async function measureDownload(bytes, iterations) { }, (error) => { console.error(`Error: ${error}`); - }, + } ); } @@ -204,7 +214,7 @@ async function measureUpload(bytes, iterations) { }, (error) => { console.error(`Error: ${error}`); - }, + } ); } @@ -265,21 +275,21 @@ function parseArgs() { async function speedTest() { const args = parseArgs(); const [ping, serverLocationData, { ip, loc, colo }] = await Promise.all([measureLatency(), fetchServerLocationData(), fetchCfCdnCgiTrace()]); - flushing = !args.json + flushing = !args.json; const city = serverLocationData[colo]; results = { - server_location: `${city} (${colo})`, + server_location: city ? `${city} (${colo})` : colo, your_ip: `${ip} (${loc})`, latency: { min: ping[0].toFixed(2), max: ping[1].toFixed(2), average: ping[2].toFixed(2), median: ping[3].toFixed(2), - jitter: ping[4].toFixed(2) + jitter: ping[4].toFixed(2), }, download_speeds: [], - upload_speeds: [] + upload_speeds: [], }; logInfo("Server Location", results.server_location); logInfo("Your IP", results.your_ip); @@ -307,7 +317,7 @@ async function speedTest() { const testUp2 = await measureUpload(101000, 10); const testUp3 = await measureUpload(1001000, 8); const uploadTests = [...testUp1, ...testUp2, ...testUp3]; - logUploadSpeed(uploadTests) + logUploadSpeed(uploadTests); // Conditional output based on --json option if (args.json) { @@ -332,5 +342,5 @@ module.exports = { logDownloadSpeed, logUploadSpeed, parseArgs, - speedTest + speedTest, }; From 2cb89f9b9af0f43c75ed2ea8f6c0a8519766b7c8 Mon Sep 17 00:00:00 2001 From: Admir Skomorac Date: Mon, 29 Dec 2025 16:36:24 +0100 Subject: [PATCH 2/2] docs: add logging for API errors as suggested by code review --- lib.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib.js b/lib.js index cc15db7..a33dd92 100644 --- a/lib.js +++ b/lib.js @@ -54,17 +54,18 @@ async function fetchServerLocationData() { try { res = JSON.parse(responseData); } catch (e) { + console.error("Failed to parse server location data:", e); return {}; } if (!Array.isArray(res)) { + console.warn(`Expected server location data to be an array, but got ${typeof res}.`); return {}; } return res.reduce((data, { iata, city }) => { // Bypass prettier "no-assign-param" rules const data1 = data; - data1[iata] = city; return data1; }, {});