1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-19 12:59:36 +02:00

fix(geocoding): improve error handling and response validation in search_google function

This commit is contained in:
Sean Morley 2025-06-16 11:47:36 -04:00
parent cee9345bf1
commit 930c98a607
2 changed files with 58 additions and 39 deletions

View file

@ -6,34 +6,43 @@ from django.conf import settings
# ----------------- # -----------------
# SEARCHING # SEARCHING
# -----------------
def search_google(query): def search_google(query):
try:
api_key = settings.GOOGLE_MAPS_API_KEY api_key = settings.GOOGLE_MAPS_API_KEY
if not api_key:
return {"error": "Missing Google Maps API key"}
url = "https://maps.googleapis.com/maps/api/place/textsearch/json" url = "https://maps.googleapis.com/maps/api/place/textsearch/json"
params = {'query': query, 'key': api_key} params = {'query': query, 'key': api_key}
response = requests.get(url, params=params) response = requests.get(url, params=params, timeout=(2, 5))
response.raise_for_status()
data = response.json() data = response.json()
if data.get("status") != "OK":
return {
"error": f"Google Maps API error: {data.get('status')}",
"message": data.get("error_message", "")
}
results = [] results = []
for r in data.get("results", []): for place in data.get("results", []):
location = r.get("geometry", {}).get("location", {}) location = place.get("geometry", {}).get("location", {})
types = r.get("types", []) types = place.get("types", [])
# First type is often most specific (e.g., 'restaurant', 'locality')
primary_type = types[0] if types else None primary_type = types[0] if types else None
category = _extract_google_category(types) category = _extract_google_category(types)
addresstype = _infer_addresstype(primary_type) addresstype = _infer_addresstype(primary_type)
importance = None importance = None
if r.get("user_ratings_total") and r.get("rating"): rating = place.get("rating")
# Simple importance heuristic based on popularity and quality ratings_total = place.get("user_ratings_total")
importance = round(float(r["rating"]) * r["user_ratings_total"] / 100, 2) if rating is not None and ratings_total:
importance = round(float(rating) * ratings_total / 100, 2)
results.append({ results.append({
"lat": location.get("lat"), "lat": location.get("lat"),
"lon": location.get("lng"), "lon": location.get("lng"),
"name": r.get("name"), "name": place.get("name"),
"display_name": r.get("formatted_address"), "display_name": place.get("formatted_address"),
"type": primary_type, "type": primary_type,
"category": category, "category": category,
"importance": importance, "importance": importance,
@ -41,12 +50,16 @@ def search_google(query):
"powered_by": "google", "powered_by": "google",
}) })
# order by importance if available if results:
if results and any("importance" in r for r in results): results.sort(key=lambda r: r["importance"] if r["importance"] is not None else 0, reverse=True)
results.sort(key=lambda x: x.get("importance", 0), reverse=True)
return results return results or {"error": "No results found"}
except requests.exceptions.RequestException as e:
return {"error": "Network error while contacting Google Maps", "details": str(e)}
except Exception as e:
return {"error": "Unexpected error during Google search", "details": str(e)}
def _extract_google_category(types): def _extract_google_category(types):
# Basic category inference based on common place types # Basic category inference based on common place types

View file

@ -172,7 +172,12 @@
} }
let res = await fetch(`/api/reverse-geocode/search/?query=${query}`); let res = await fetch(`/api/reverse-geocode/search/?query=${query}`);
console.log(res); console.log(res);
let data = (await res.json()) as GeocodeSearchResult[]; let data = (await res.json()) as GeocodeSearchResult[] | { error: string };
if ('error' in data) {
places = [];
noPlaces = true;
} else {
places = data; places = data;
if (data.length === 0) { if (data.length === 0) {
noPlaces = true; noPlaces = true;
@ -180,6 +185,7 @@
noPlaces = false; noPlaces = false;
} }
} }
}
async function reverseGeocode(force_update: boolean = false) { async function reverseGeocode(force_update: boolean = false) {
let res = await fetch( let res = await fetch(