Unsupported EPC schema versions are skipped with a warning, not a crash

An unrecognised schema_type used to raise ValueError and abort the whole
call; now from_api_response logs a warning and returns None so one
unmapped cert doesn't break a batch. Schema 15.0 already has a mapper
(PR #1531) so it's unaffected; only genuinely unmapped versions skip.
This commit is contained in:
Jun-te Kim 2026-07-10 11:17:07 +00:00
parent 066cac8cb1
commit b540cf1ca2
3 changed files with 19 additions and 11 deletions

View file

@ -2946,11 +2946,12 @@ class EpcPropertyDataMapper:
return [EpcPropertyDataMapper._map_energy_element(e) for e in elements] return [EpcPropertyDataMapper._map_energy_element(e) for e in elements]
@staticmethod @staticmethod
def from_api_response(data: Dict[str, Any]) -> "EpcPropertyData": def from_api_response(data: Dict[str, Any]) -> Optional["EpcPropertyData"]:
""" """
Dispatch to the correct schema mapper based on schema_type. Dispatch to the correct schema mapper based on schema_type.
Supports RdSAP-Schema-21.0.0 and RdSAP-Schema-21.0.1 only. Any `schema_type` not in the allow-list below (the schemas with a
Raises ValueError for unsupported schemas add cases here as needed. dedicated mapper) is logged as a warning and skipped returns None
rather than raising, so one unrecognised cert doesn't break a batch.
""" """
data = _normalize_shower_outlets(data) data = _normalize_shower_outlets(data)
@ -3053,7 +3054,12 @@ class EpcPropertyDataMapper:
"mapped to EpcPropertyData, which models a single dwelling." "mapped to EpcPropertyData, which models a single dwelling."
) )
else: else:
raise ValueError(f"Unsupported EPC schema: {schema!r}") logger.warning(
"Unsupported EPC schema %r — skipping this EPC (uprn=%s)",
schema,
data.get("uprn"),
)
return None
return _clear_basement_flag_when_system_built( return _clear_basement_flag_when_system_built(
_with_renewable_heat_incentive( _with_renewable_heat_incentive(

View file

@ -38,7 +38,7 @@ class EpcClientService:
except (TypeError, ValueError): except (TypeError, ValueError):
return None return None
def get_by_certificate_number(self, cert_num: str) -> EpcPropertyData: def get_by_certificate_number(self, cert_num: str) -> Optional[EpcPropertyData]:
raw = call_with_retry(lambda: self._fetch_certificate(cert_num)) raw = call_with_retry(lambda: self._fetch_certificate(cert_num))
return EpcPropertyDataMapper.from_api_response(raw) return EpcPropertyDataMapper.from_api_response(raw)

View file

@ -1,5 +1,3 @@
import pytest
from datatypes.epc.domain.mapper import EpcPropertyDataMapper from datatypes.epc.domain.mapper import EpcPropertyDataMapper
from datatypes.epc.domain.epc_property_data import EpcPropertyData from datatypes.epc.domain.epc_property_data import EpcPropertyData
@ -23,9 +21,13 @@ def test_from_api_response_rdsap_21_0_1(rdsap_21_0_1_cert):
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Test 3: unknown schema_type → ValueError # Test 3: unknown schema_type → logged warning, None returned (not raised)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
def test_from_api_response_unknown_schema_raises(): def test_from_api_response_unknown_schema_returns_none(caplog):
with pytest.raises(ValueError, match="Unsupported EPC schema"): with caplog.at_level("WARNING"):
EpcPropertyDataMapper.from_api_response({"schema_type": "RdSAP-Schema-99.0.0"}) result = EpcPropertyDataMapper.from_api_response(
{"schema_type": "RdSAP-Schema-99.0.0"}
)
assert result is None
assert "RdSAP-Schema-99.0.0" in caplog.text