The error handling in GetWeather.js throws errors without providing specific details about what went wrong, making debugging difficult if API calls fail.
The error handling in GetWeather.js is minimal and lacks specific error information:
const Functions = {
makeHttpRequest: async (params) => {
if (testCase === "invalid_api_key") {
return {
error: {
status: 401,
statusText: "Unauthorized",
message: "Invalid API key. Please see http://openweathermap.org/faq#error401 for more info."
}
};
} else if (testCase === "invalid_location") {
return {
error: {
status: 404,
statusText: "Not Found",
message: "zip code not found"
}
};
} else if (testCase === "rate_limit") {
return {
error: {
status: 429,
statusText: "Too Many Requests",
message: "API rate limit exceeded"
}
};
} else if (testCase === "server_error") {
return {
error: {
status: 500,
statusText: "Internal Server Error",
message: "Internal server error"
}
};
} else if (testCase === "network_error") {
throw new Error("Network error: Unable to reach API endpoint");
} else {
if (params.url.includes("geo/1.0/zip")) {
return {
data: {
lat: 40.7128,
lon: -74.0060
}
};
} else if (params.url.includes("data/2.5/weather")) {
return {
data: {
weather: [
{
id: 800
}
],
main: {
temp: 20
}
}
};
}
}
}
};
const getWeather = (args, secrets) => {
return new Promise(async (resolve) => {
try {
const geoCodingRequest = await Functions.makeHttpRequest({
url: "http://api.openweathermap.org/geo/1.0/zip",
method: "GET",
params: { zip: `${args[0]},${args[1]}`, appid: secrets.apiKey }
});
if (geoCodingRequest.error) {
throw Error("Request failed, try checking the params provided");
}
const weatherRequest = await Functions.makeHttpRequest({
url: "https://api.openweathermap.org/data/2.5/weather",
method: "GET",
params: {
lat: geoCodingRequest.data.lat,
lon: geoCodingRequest.data.lon,
appid: secrets.apiKey
}
});
if (weatherRequest.error) {
throw Error("Request failed, try checking the params provided");
}
const weather_id = weatherRequest.data.weather[0].id;
const weather_id_x = Math.floor(weather_id / 100);
let weather_enum;
if (weather_id_x === 2) weather_enum = 3;
else if (weather_id_x === 3 || weather_id_x === 5) weather_enum = 2;
else if (weather_id_x === 6) weather_enum = 5;
else if (weather_id === 800) weather_enum = 0;
else if (weather_id_x === 8) weather_enum = 1;
else weather_enum = 4;
resolve([weather_enum, Math.round(weatherRequest.data.main.temp)]);
} catch (error) {
console.error("Error in getWeather:", error.message);
resolve([0, 0]);
}
});
};
const getWeatherImproved = (args, secrets) => {
return new Promise(async (resolve) => {
try {
const geoCodingRequest = await Functions.makeHttpRequest({
url: "http://api.openweathermap.org/geo/1.0/zip",
method: "GET",
params: { zip: `${args[0]},${args[1]}`, appid: secrets.apiKey }
});
if (geoCodingRequest.error) {
const errorDetails = {
message: "Geocoding request failed",
status: geoCodingRequest.error.status,
statusText: geoCodingRequest.error.statusText,
details: geoCodingRequest.error.message,
params: {
zip: `${args[0]},${args[1]}`,
appid: "API key used (masked)"
}
};
throw Error(JSON.stringify(errorDetails));
}
const weatherRequest = await Functions.makeHttpRequest({
url: "https://api.openweathermap.org/data/2.5/weather",
method: "GET",
params: {
lat: geoCodingRequest.data.lat,
lon: geoCodingRequest.data.lon,
appid: secrets.apiKey
}
});
if (weatherRequest.error) {
const errorDetails = {
message: "Weather data request failed",
status: weatherRequest.error.status,
statusText: weatherRequest.error.statusText,
details: weatherRequest.error.message,
params: {
lat: geoCodingRequest.data.lat,
lon: geoCodingRequest.data.lon,
appid: "API key used (masked)"
}
};
throw Error(JSON.stringify(errorDetails));
}
const weather_id = weatherRequest.data.weather[0].id;
const weather_id_x = Math.floor(weather_id / 100);
let weather_enum;
if (weather_id_x === 2) weather_enum = 3;
else if (weather_id_x === 3 || weather_id_x === 5) weather_enum = 2;
else if (weather_id_x === 6) weather_enum = 5;
else if (weather_id === 800) weather_enum = 0;
else if (weather_id_x === 8) weather_enum = 1;
else weather_enum = 4;
resolve([weather_enum, Math.round(weatherRequest.data.main.temp)]);
} catch (error) {
console.error("Error in getWeatherImproved:", error.message);
let errorObj = { message: error.message };
try {
if (error.message.startsWith('{')) {
errorObj = JSON.parse(error.message);
}
} catch (e) {
}
console.error("Detailed error:", errorObj);
resolve([0, 0, { error: errorObj }]);
}
});
};
async function runTests() {
const args = ["10001", "US"];
const secrets = { apiKey: "mock_api_key" };
console.log("Testing Error Handling Issues in GetWeather.js:");
console.log("\nTest Case 1: Invalid API Key");
testCase = "invalid_api_key";
console.log("Original implementation:");
try {
const result1 = await getWeather(args, secrets);
console.log(`Result: ${JSON.stringify(result1)}`);
} catch (error) {
console.log(`Error: ${error.message}`);
}
console.log("\nImproved implementation:");
try {
const result1Improved = await getWeatherImproved(args, secrets);
console.log(`Result: ${JSON.stringify(result1Improved)}`);
} catch (error) {
console.log(`Error: ${error.message}`);
}
console.log("\nTest Case 2: Invalid Location");
testCase = "invalid_location";
console.log("Original implementation:");
try {
const result2 = await getWeather(args, secrets);
console.log(`Result: ${JSON.stringify(result2)}`);
} catch (error) {
console.log(`Error: ${error.message}`);
}
console.log("\nImproved implementation:");
try {
const result2Improved = await getWeatherImproved(args, secrets);
console.log(`Result: ${JSON.stringify(result2Improved)}`);
} catch (error) {
console.log(`Error: ${error.message}`);
}
console.log("\nTest Case 3: Network Error");
testCase = "network_error";
console.log("Original implementation:");
try {
const result3 = await getWeather(args, secrets);
console.log(`Result: ${JSON.stringify(result3)}`);
} catch (error) {
console.log(`Error: ${error.message}`);
}
console.log("\nImproved implementation:");
try {
const result3Improved = await getWeatherImproved(args, secrets);
console.log(`Result: ${JSON.stringify(result3Improved)}`);
} catch (error) {
console.log(`Error: ${error.message}`);
}
}
let testCase = "success";
runTests();
This PoC demonstrates the issues with the current error handling in GetWeather.js by comparing it with an improved implementation:
The PoC shows how the improved error handling makes debugging easier by providing actionable information about what went wrong and how to fix it.