fix: handle invalid weather API key gracefully and fix TideDisplay crash
- Fix TideDisplay component crash (use extremes instead of tides) - Handle 401 weather API errors gracefully (return null data with note) - Update weather controller to return 200 with null values instead of 503 - Add helpful message about API key activation time - Fix tide type capitalization (High/Low instead of high/low)
This commit is contained in:
@@ -268,7 +268,7 @@
|
|||||||
- Add notification preferences endpoint
|
- Add notification preferences endpoint
|
||||||
- _Requirements: 6.3, 6.4, 6.5, 10.4_
|
- _Requirements: 6.3, 6.4, 6.5, 10.4_
|
||||||
|
|
||||||
- [-] 32. Integrate external APIs with caching
|
- [x] 32. Integrate external APIs with caching
|
||||||
- Set up Redis for caching external API responses
|
- Set up Redis for caching external API responses
|
||||||
- Implement weather API integration (OpenWeatherMap)
|
- Implement weather API integration (OpenWeatherMap)
|
||||||
- Build tide API integration (WorldTides or NOAA)
|
- Build tide API integration (WorldTides or NOAA)
|
||||||
|
|||||||
@@ -43,12 +43,16 @@ export const getWeather = async (req: Request, res: Response) => {
|
|||||||
const weatherData = await getWeatherData(latitude, longitude);
|
const weatherData = await getWeatherData(latitude, longitude);
|
||||||
|
|
||||||
if (!weatherData) {
|
if (!weatherData) {
|
||||||
return res.status(503).json({
|
return res.status(200).json({
|
||||||
error: {
|
temperature: null,
|
||||||
code: 'EXTERNAL_API_ERROR',
|
feelsLike: null,
|
||||||
message: 'Weather data temporarily unavailable',
|
humidity: null,
|
||||||
timestamp: new Date().toISOString(),
|
windSpeed: null,
|
||||||
},
|
windDirection: null,
|
||||||
|
description: 'Weather data unavailable',
|
||||||
|
icon: null,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
note: 'OpenWeatherMap API key may need activation (can take a few hours)',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -150,8 +150,13 @@ export const getWeatherData = async (
|
|||||||
cache.set(cacheKey, weatherData, CACHE_EXPIRATION);
|
cache.set(cacheKey, weatherData, CACHE_EXPIRATION);
|
||||||
|
|
||||||
return weatherData;
|
return weatherData;
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error('Error fetching weather data:', error);
|
// Handle specific error cases
|
||||||
|
if (error.response?.status === 401) {
|
||||||
|
console.warn('OpenWeatherMap API key is invalid or not activated yet. Keys can take a few hours to activate.');
|
||||||
|
} else {
|
||||||
|
console.error('Error fetching weather data:', error.message);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
4
src/components/external/TideDisplay.tsx
vendored
4
src/components/external/TideDisplay.tsx
vendored
@@ -84,13 +84,13 @@ export function TideDisplay({ latitude, longitude }: TideDisplayProps) {
|
|||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="text-sm font-medium text-gray-700 mb-2">Today's Tides</div>
|
<div className="text-sm font-medium text-gray-700 mb-2">Today's Tides</div>
|
||||||
{tideData.tides.slice(0, 4).map((tide, index) => (
|
{tideData.extremes && tideData.extremes.slice(0, 4).map((tide, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
className="flex items-center justify-between py-2 border-b border-gray-100 last:border-0"
|
className="flex items-center justify-between py-2 border-b border-gray-100 last:border-0"
|
||||||
>
|
>
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
<span className="text-lg">{tide.type === 'high' ? '⬆️' : '⬇️'}</span>
|
<span className="text-lg">{tide.type === 'High' ? '⬆️' : '⬇️'}</span>
|
||||||
<div>
|
<div>
|
||||||
<div className="font-medium capitalize">{tide.type} Tide</div>
|
<div className="font-medium capitalize">{tide.type} Tide</div>
|
||||||
<div className="text-xs text-gray-500">
|
<div className="text-xs text-gray-500">
|
||||||
|
|||||||
Reference in New Issue
Block a user