diff --git a/client/src/components/WeatherWidget.tsx b/client/src/components/WeatherWidget.tsx index 7b4cf61..6a93cf5 100644 --- a/client/src/components/WeatherWidget.tsx +++ b/client/src/components/WeatherWidget.tsx @@ -121,11 +121,6 @@ export default function WeatherWidget() { const { data: weather, isLoading, error } = useQuery({ queryKey: ['/api/weather/current'], refetchInterval: 30 * 60 * 1000, // Refetch every 30 minutes - // Données valables jusqu'au prochain rafraîchissement : pas de rechargement au remontage - staleTime: 30 * 60 * 1000, - // Pas de nouvel essai : un 404 (météo non configurée) ne changera pas, et le - // serveur peut appeler l'API météo externe à chaque requête - retry: false, }); diff --git a/server/routes.ts b/server/routes.ts index 8dd549d..4f05128 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -5421,58 +5421,55 @@ RÉSUMÉ DU SCAN const today = new Date().toISOString().split('T')[0]; const previousYearDate = weatherService.getPreviousYearDate(); - // Check if we already have today's data (deux lectures indépendantes) + // Lectures du cache indépendantes : en parallèle let [currentYearData, previousYearData] = await Promise.all([ storage.getWeatherData(today, true), storage.getWeatherData(previousYearDate, false), ]); - // Les appels à l'API pour l'année en cours et l'année précédente sont - // indépendants : ils sont lancés en parallèle - await Promise.all([ - (async () => { - // Fetch current year data if not in cache - if (!currentYearData) { - console.log("🌤️ [FETCH] Fetching current weather data from API"); - const apiData = await weatherService.fetchCurrentWeather(settings); - if (apiData) { - const weatherData = weatherService.convertApiDataToWeatherData(apiData, settings.location, true); - if (weatherData) { - try { - currentYearData = await storage.createWeatherData(weatherData); - console.log("✅ [CACHE] Current year data saved to cache"); - } catch (error: any) { - console.warn("⚠️ [CACHE] Could not save current year data (may already exist):", error.message); - // Récupérer les données existantes au lieu de créer - currentYearData = await storage.getWeatherData(today, true); - } - } + // Les appels à l'API météo restent séquentiels : lancés en parallèle, + // Visual Crossing peut refuser la seconde requête d'une même clé (limite + // de requêtes simultanées) et la comparaison avec l'an dernier disparaît. + + // Fetch current year data if not in cache + if (!currentYearData) { + console.log("🌤️ [FETCH] Fetching current weather data from API"); + const apiData = await weatherService.fetchCurrentWeather(settings); + if (apiData) { + const weatherData = weatherService.convertApiDataToWeatherData(apiData, settings.location, true); + if (weatherData) { + try { + currentYearData = await storage.createWeatherData(weatherData); + console.log("✅ [CACHE] Current year data saved to cache"); + } catch (error: any) { + console.warn("⚠️ [CACHE] Could not save current year data (may already exist):", error.message); + // Récupérer les données existantes au lieu de créer + currentYearData = await storage.getWeatherData(today, true); } } - })(), - (async () => { - // Fetch previous year data if not in cache - if (!previousYearData) { - console.log("🌤️ [FETCH] Fetching previous year weather data from API"); - const apiData = await weatherService.fetchPreviousYearWeather(settings, previousYearDate); - if (apiData) { - const weatherData = weatherService.convertApiDataToWeatherData(apiData, settings.location, false); - if (weatherData) { - try { - previousYearData = await storage.createWeatherData(weatherData); - console.log("✅ [CACHE] Previous year data saved to cache"); - } catch (error: any) { - console.warn("⚠️ [CACHE] Could not save previous year data (may already exist):", error.message); - // Récupérer les données existantes au lieu de créer - previousYearData = await storage.getWeatherData(previousYearDate, false); - } - } - } else { - console.warn("⚠️ [HISTORY] Could not fetch historical data - continuing with current year only"); + } + } + + // Fetch previous year data if not in cache + if (!previousYearData) { + console.log("🌤️ [FETCH] Fetching previous year weather data from API"); + const apiData = await weatherService.fetchPreviousYearWeather(settings, previousYearDate); + if (apiData) { + const weatherData = weatherService.convertApiDataToWeatherData(apiData, settings.location, false); + if (weatherData) { + try { + previousYearData = await storage.createWeatherData(weatherData); + console.log("✅ [CACHE] Previous year data saved to cache"); + } catch (error: any) { + console.warn("⚠️ [CACHE] Could not save previous year data (may already exist):", error.message); + // Récupérer les données existantes au lieu de créer + previousYearData = await storage.getWeatherData(previousYearDate, false); } } - })(), - ]); + } else { + console.warn("⚠️ [HISTORY] Could not fetch historical data - continuing with current year only"); + } + } // Repli : si l'API historique a échoué (quota épuisé, panne, plan sans // accès à l'historique), reprendre la ligne en cache la plus proche de diff --git a/server/weatherService.ts b/server/weatherService.ts index 31bc58d..8a681d4 100644 --- a/server/weatherService.ts +++ b/server/weatherService.ts @@ -27,7 +27,8 @@ export class WeatherService { const response = await fetch(url); if (!response.ok) { - console.error(`Weather API error: ${response.status} ${response.statusText}`); + const reason = (await response.text().catch(() => '')).slice(0, 300); + console.error(`Weather API error: ${response.status} ${response.statusText} ${reason}`); return null; } @@ -51,7 +52,9 @@ export class WeatherService { const response = await fetch(url); if (!response.ok) { - console.error(`🌤️ [ERROR] Weather API error for previous year: ${response.status} ${response.statusText}`); + // Visual Crossing explique le refus dans le corps (quota, plan, clé...) + const reason = (await response.text().catch(() => '')).slice(0, 300); + console.error(`🌤️ [ERROR] Weather API error for previous year: ${response.status} ${response.statusText} ${reason}`); // Pour les données historiques, certains comptes peuvent ne pas avoir accès if (response.status === 401) {