谷歌地理编码API遇geometry未定义错误,求修正.geometry.location的其他方法
Hey there! That error pops up because your code is trying to access geometry on data.results[0], but data.results[0] is undefined. Let's break down why this happens, fix it properly, and look at safer ways to handle that geometry.location access.
Why the Error Occurs
Your current code only checks for !data or data.status === "ZERO_RESULTS", but Google's Geocoding API can return several other statuses that leave data.results empty or undefined. For example:
INVALID_REQUEST: Malformed request (like a poorly formatted address)OVER_QUERY_LIMIT: You've hit your API quota limitREQUEST_DENIED: Invalid API key or missing permissionsUNKNOWN_ERROR: Server-side issue with Google's service
In all these cases, data.results might be an empty array or undefined, making data.results[0] undefined—and trying to access .geometry on that throws the error you're seeing.
Fixed Code with Robust Error Handling
Here's an updated version of your function that covers all these edge cases and prevents the error:
const axios = require("axios"); const HttpError = require("../models/http-error"); const API_KEY = "BlablablaBlablabla"; async function getCoordsForAddress(address) { try { const response = await axios.get( `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=${API_KEY}` ); const data = response.data; // Check if results exist and have at least one entry if (!data || !data.results || data.results.length === 0) { let errorMessage = "Could not find location for the specified address."; // Add context based on API status if available if (data?.status) { switch(data.status) { case "OVER_QUERY_LIMIT": errorMessage = "API quota exceeded. Check your Google Cloud console."; break; case "REQUEST_DENIED": errorMessage = "API request denied. Verify your API key and permissions."; break; case "INVALID_REQUEST": errorMessage = "Invalid address format or missing parameters."; break; } } throw new HttpError(errorMessage, 422); } const coordinates = data.results[0].geometry.location; return coordinates; } catch (err) { // Catch network or unexpected errors from axios throw new HttpError("Failed to connect to geocoding service.", 500); } } module.exports = getCoordsForAddress;
Safer Alternatives to Access .geometry.location
If you want a more concise way to avoid the undefined error (while still keeping basic checks), here are two options:
Optional Chaining Operator (
?.)
This lets you safely access nested properties without throwing an error if any intermediate value is undefined:const coordinates = data.results?.[0]?.geometry?.location; if (!coordinates) { throw new HttpError("Could not retrieve coordinates for the address.", 422); } return coordinates;Explicit Nested Checks
Manually verify each level of the nested object before accessing the final property:if (!data?.results || !data.results[0]?.geometry?.location) { throw new HttpError("Could not retrieve coordinates for the address.", 422); } const coordinates = data.results[0].geometry.location; return coordinates;
Just note: While these shorthand methods prevent the immediate error, they don't give you details about why the coordinates are missing. The full error handling approach above is better for debugging and user feedback.
内容的提问来源于stack exchange,提问作者fyardlest

