Describe the Bug
When calling find_campgrounds(rec_area_id=[3]) (or any GoingToCamp recreation area), the provider raises a KeyError because campground_details dictionary doesn't contain the expected keys.
Camply Version
- camply version: 0.33.1
- Python version: 3.12
Error Message
Full traceback:
File ".../camply/providers/going_to_camp/going_to_camp_provider.py", line 427, in _process_facilities_responses
self.campground_details[facility.resource_location_id]
KeyError: -2147483647
Steps to Reproduce
from camply.providers import GoingToCamp
provider = GoingToCamp()
campgrounds = provider.find_campgrounds(rec_area_id=[3]) # Washington State Parks
# Raises KeyError: -2147483647
Root Cause Analysis
I debugged this issue and found the root cause:
-
LIST_CAMPGROUNDS API returns facilities with both resourceLocationId and rootMapId:
# Example facility from LIST_CAMPGROUNDS:
{
"resourceLocationId": -2147483647,
"rootMapId": -2147483396,
"localizedValues": [{"fullName": "Alta Lake State Park"}],
...
}
-
CAMP_DETAILS API returns regional map data, NOT per-campground details. All entries have resourceLocationId=None:
# All 6 entries from CAMP_DETAILS for Washington State Parks:
[
{"resourceLocationId": None, "mapId": -2147483648, ...}, # Regional map 1
{"resourceLocationId": None, "mapId": -2147483643, ...}, # Regional map 2
# ... all have resourceLocationId=None
]
-
The bug is in find_facilities_per_recreation_area() at lines 287-288:
for camp_details in self._api_request(rec_area_id, "CAMP_DETAILS"):
self.campground_details[camp_details["resourceLocationId"]] = camp_details
This creates {None: <last_entry>} because all entries have resourceLocationId=None.
-
The crash happens in _process_facilities_responses() at line 427:
self.campground_details[facility.resource_location_id] # KeyError!
Affected Recreation Areas
All GoingToCamp recreation areas are affected:
- Washington State Parks (rec_area_id=3) - 78 campgrounds
- Wisconsin State Parks (rec_area_id=7) - 50 campgrounds
- BC Parks (rec_area_id=1) - 110 campgrounds
- Parks Canada (rec_area_id=2) - 76 campgrounds
- Ontario Parks, Maryland State Parks, etc.
Proposed Fix
The LIST_CAMPGROUNDS response already contains rootMapId for each facility. We should use this directly instead of the broken CAMP_DETAILS lookup.
Before (buggy):
def _process_facilities_responses(self, rec_area, facility):
self.campground_details[facility.resource_location_id] # KeyError!
facility.id = _fetch_nested_key(
self.campground_details, facility.resource_location_id, "mapId"
)
After (fixed):
# In find_facilities_per_recreation_area(), store rootMapId from LIST_CAMPGROUNDS:
self._root_map_ids = {
f['resourceLocationId']: f.get('rootMapId')
for f in api_response
}
# In _process_facilities_responses(), use rootMapId directly:
def _process_facilities_responses(self, rec_area, facility):
map_id = self._root_map_ids.get(facility.resource_location_id)
facility.id = map_id
I can submit a PR with this fix if you'd like. I've already tested it locally and confirmed it works for all the recreation areas listed above.
Describe the Bug
When calling
find_campgrounds(rec_area_id=[3])(or any GoingToCamp recreation area), the provider raises aKeyErrorbecausecampground_detailsdictionary doesn't contain the expected keys.Camply Version
Error Message
Full traceback:
Steps to Reproduce
Root Cause Analysis
I debugged this issue and found the root cause:
LIST_CAMPGROUNDSAPI returns facilities with bothresourceLocationIdandrootMapId:CAMP_DETAILSAPI returns regional map data, NOT per-campground details. All entries haveresourceLocationId=None:The bug is in
find_facilities_per_recreation_area()at lines 287-288:This creates
{None: <last_entry>}because all entries haveresourceLocationId=None.The crash happens in
_process_facilities_responses()at line 427:Affected Recreation Areas
All GoingToCamp recreation areas are affected:
Proposed Fix
The
LIST_CAMPGROUNDSresponse already containsrootMapIdfor each facility. We should use this directly instead of the brokenCAMP_DETAILSlookup.Before (buggy):
After (fixed):
I can submit a PR with this fix if you'd like. I've already tested it locally and confirmed it works for all the recreation areas listed above.