Enhance country data retrieval and error handling in WatchedMap component

- Improved country code extraction logic to handle null values and prevent rendering errors.
- Added error handling for API responses to ensure graceful degradation in case of failures.
- Updated the logic for determining country codes from GeoJSON features to account for missing values.
- Set default values for watched items and summary to avoid application crashes during data fetch failures.
This commit is contained in:
Danilo Reyes
2025-12-28 22:13:19 -06:00
parent 1c0ca487fe
commit 4caba81599
2 changed files with 44 additions and 7 deletions

View File

@@ -218,7 +218,22 @@ async def get_musicbrainz_artist_country(mbid: str) -> Optional[str]:
)
if response.status_code == 200:
data = response.json()
# Check area relations for country
# First, check direct country field
if "country" in data and data["country"]:
country = data["country"]
if isinstance(country, str) and len(country) == 2:
return country.upper()
# Second, check area.iso-3166-1-codes
if "area" in data and data["area"]:
area = data["area"]
if "iso-3166-1-codes" in area and area["iso-3166-1-codes"]:
codes = area["iso-3166-1-codes"]
if isinstance(codes, list) and len(codes) > 0:
return codes[0].upper()
# Third, check area relations for country
if "relations" in data:
for relation in data["relations"]:
if relation.get("type") == "origin" and "area" in relation:

View File

@@ -59,11 +59,25 @@ export default function WatchedMap() {
fetch('/api/watched/summary'),
])
if (!watchedRes.ok) {
throw new Error(`Watched API error: ${watchedRes.status}`)
}
if (!pinsRes.ok) {
throw new Error(`Pins API error: ${pinsRes.status}`)
}
if (!summaryRes.ok) {
throw new Error(`Summary API error: ${summaryRes.status}`)
}
setWatchedItems(await watchedRes.json())
setPins(await pinsRes.json())
setSummary(await summaryRes.json())
} catch (error) {
console.error('Failed to fetch data:', error)
// Set empty defaults to prevent rendering errors
setWatchedItems([])
setPins([])
setSummary({})
}
}
@@ -123,7 +137,8 @@ export default function WatchedMap() {
}
}
const getCountryCount = (countryCode: string): number => {
const getCountryCount = (countryCode: string | null): number => {
if (!countryCode) return 0
const data = summary[countryCode] || {}
return (data.movie || 0) + (data.show || 0)
}
@@ -133,7 +148,8 @@ export default function WatchedMap() {
return Math.max(...counts, 1)
}
const getCountryColor = (countryCode: string): string => {
const getCountryColor = (countryCode: string | null): string => {
if (!countryCode) return '#e0e0e0'
const count = getCountryCount(countryCode)
const maxCount = getMaxCount()
if (count === 0) return '#e0e0e0'
@@ -228,21 +244,27 @@ export default function WatchedMap() {
<GeoJSON
data={worldGeoJson}
style={(feature) => {
const code = feature?.properties?.ISO_A2 || feature?.properties?.ISO_A3?.substring(0, 2)
const isoA2 = feature?.properties?.ISO_A2
const isoA3 = feature?.properties?.ISO_A3
const code = isoA2 || (isoA3 && typeof isoA3 === 'string' ? isoA3.substring(0, 2) : null) || null
return {
fillColor: getCountryColor(code),
fillColor: getCountryColor(code || ''),
fillOpacity: 0.7,
color: '#666',
weight: 1,
}
}}
onEachFeature={(feature, layer) => {
const code = feature?.properties?.ISO_A2 || feature?.properties?.ISO_A3?.substring(0, 2)
const isoA2 = feature?.properties?.ISO_A2
const isoA3 = feature?.properties?.ISO_A3
const code = isoA2 || (isoA3 && typeof isoA3 === 'string' ? isoA3.substring(0, 2) : null) || null
if (!code) return
const count = getCountryCount(code)
const data = summary[code] || {}
layer.bindPopup(`
<strong>${feature.properties.NAME || code}</strong><br/>
<strong>${feature.properties?.NAME || code}</strong><br/>
Watched: ${count}<br/>
${data.movie ? `Movies: ${data.movie}<br/>` : ''}
${data.show ? `Shows: ${data.show}` : ''}