diff --git a/src/api/CHANGELOG.md b/src/api/CHANGELOG.md index 76b059f7..72c347ee 100644 --- a/src/api/CHANGELOG.md +++ b/src/api/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to - Upgrade geoalchemy2 to `0.16.0` - Upgrade pyjwt to `2.10.0` - Upgrade setuptools to `75.5.0` +- Send DB query details on Statique API errors only in debug mode ## [0.14.0] - 2024-11-15 diff --git a/src/api/qualicharge/api/v1/routers/static.py b/src/api/qualicharge/api/v1/routers/static.py index 7d1fceda..b32630e3 100644 --- a/src/api/qualicharge/api/v1/routers/static.py +++ b/src/api/qualicharge/api/v1/routers/static.py @@ -276,8 +276,8 @@ async def bulk( dtype_backend="pyarrow", ) - importer = StatiqueImporter(df, session.connection()) transaction = session.begin_nested() + importer = StatiqueImporter(df, transaction.session.connection()) try: importer.save() except ( @@ -285,8 +285,15 @@ async def bulk( IntegrityError, OperationalError, PGError, - ObjectDoesNotExist, ) as err: + transaction.rollback() + detail = "Point of charge (or related entry) is not consistent" + if settings.DEBUG: + detail = str(err) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail=detail + ) from err + except ObjectDoesNotExist as err: transaction.rollback() raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail=str(err) diff --git a/src/api/tests/api/v1/routers/test_statique.py b/src/api/tests/api/v1/routers/test_statique.py index f918a009..9169458f 100644 --- a/src/api/tests/api/v1/routers/test_statique.py +++ b/src/api/tests/api/v1/routers/test_statique.py @@ -731,6 +731,43 @@ def test_bulk_for_unknown_operational_unit(client_auth, db_session): assert n_stations == 0 +def test_bulk_with_inconsistent_station_data(client_auth, db_session, monkeypatch): + """Test the /statique/bulk create endpoint with unconsistent Station data.""" + # DEBUG mode: off + monkeypatch.setattr(settings, "DEBUG", False) + station1 = StatiqueFactory.build( + id_pdc_itinerance="FR911E1111ER1", date_mise_en_service="2024-10-14" + ) + station2 = station1.model_copy( + update={ + "id_pdc_itinerance": "FR911E1111ER2", + "date_mise_en_service": "2024-10-15", + } + ) + payload = [json.loads(d.model_dump_json()) for d in [station1, station2]] + response = client_auth.post("/statique/bulk", json=payload) + + assert response.status_code == status.HTTP_400_BAD_REQUEST + json_response = response.json() + assert ( + json_response["detail"] + == "Point of charge (or related entry) is not consistent" + ) + + # DEBUG mode: on + monkeypatch.setattr(settings, "DEBUG", True) + payload = [json.loads(d.model_dump_json()) for d in [station1, station2]] + response = client_auth.post("/statique/bulk", json=payload) + + assert response.status_code == status.HTTP_400_BAD_REQUEST + json_response = response.json() + assert "psycopg.errors.CardinalityViolation" in json_response["detail"] + + # Check created statiques (if any) + n_stations = db_session.exec(select(func.count(Station.id))).one() + assert n_stations == 0 + + def test_bulk_with_outbound_sizes(client_auth): """Test the /statique/bulk create endpoint with a single or too many entries.""" id_pdc_itinerance = "FR911E1111ER1"