diff --git a/app/api/routes/weather.py b/app/api/routes/weather.py index f1e7980..d696e87 100644 --- a/app/api/routes/weather.py +++ b/app/api/routes/weather.py @@ -2,6 +2,7 @@ from fastapi import APIRouter, Query from fastapi.exceptions import RequestValidationError +from openmeteo_requests.Client import OpenMeteoRequestsError from app.core.errors.base import AppError from app.services.external_apis.weather_api import WeatherAPI @@ -55,5 +56,8 @@ def get_weather_forecast( latitude, longitude, start_date.isoformat(), end_date.isoformat(), hourly_fields=requested ) return weather_data + except OpenMeteoRequestsError as e: + # Open-Meteo failed or was unreachable: the failure is upstream, not ours + raise AppError(str(e), status_code=502, error_code="WEATHER_FETCH_FAILED") except Exception as e: raise AppError(str(e), status_code=500) \ No newline at end of file diff --git a/tests/test_api.py b/tests/test_api.py index 350cf0c..06af417 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -614,6 +614,29 @@ def fake_get_weather(self, latitude, longitude, start_date, end_date, hourly_fie "end_date": "2026-10-20", } + def test_forecast_upstream_error_is_502(self, client, monkeypatch): + from openmeteo_requests.Client import OpenMeteoRequestsError + + def fake_weather_api(*args, **kwargs): + raise OpenMeteoRequestsError("failed to request 'https://api.open-meteo.com/v1/forecast': offline") + + monkeypatch.setattr("openmeteo_requests.Client.weather_api", fake_weather_api) + + resp = client.get(self.WEATHER_URL, params=self.VALID) + assert resp.status_code == 502 + body = resp.json() + assert body["error_code"] == "WEATHER_FETCH_FAILED" + assert "offline" in body["message"] + + def test_forecast_unexpected_error_is_500(self, client, monkeypatch): + def fake_get_weather(*args, **kwargs): + raise ValueError("boom") + + monkeypatch.setattr("app.api.routes.weather.WeatherAPI.get_weather", fake_get_weather) + + resp = client.get(self.WEATHER_URL, params=self.VALID) + assert resp.status_code == 500 + @pytest.mark.parametrize( "overrides, field", [