Detail Bug Report
https://app.detail.dev/org_befd6425-a158-4e24-9d4d-1e5c08769515/bugs/bug_4b0dc27e-1a85-46f5-8317-afad12054f54
Summary
- Context: The
AppleMapsGateway interface defines methods for interacting with the Apple Maps Server API, including looking up a single place by its identifier.
- Bug: In the
HttpAppleMapsGateway implementation, the lookupPlace method attempts to deserialize the API response directly into a Place record. However, the Apple Maps Server API always returns a PlaceResults object (which contains a results array) even for single-place lookups.
- Actual vs. expected: The code expects a
Place object at the top level of the JSON response, but receives a PlaceResults object; this causes a ValueInstantiationException (or NullPointerException) because the required fields of the Place record are missing from the top-level JSON.
- Impact: The
lookupPlace method is completely non-functional and will fail whenever it is called against the live Apple Maps Server API.
Code with Bug
@Override
public Place lookupPlace(String placeId, String language) {
Objects.requireNonNull(placeId, "placeId");
String resolvedLanguage = Objects.requireNonNull(language, "language");
String queryString = "";
if (!resolvedLanguage.isBlank()) {
queryString = QUERY_PREFIX + PARAMETER_LANGUAGE + "=" + resolvedLanguage;
}
return invokeApi("place", URI.create(API_SERVER + PLACE_PATH + "/" + placeId + queryString), Place.class); // <-- BUG 🔴 Cannot deserialize PlaceResults JSON into Place record
}
Explanation
Apple’s Place Lookup endpoint (GET /v1/place/{id}) returns a PlaceResults wrapper object containing a results array of Place objects. lookupPlace currently requests Place.class from invokeApi, so Jackson attempts to construct a Place from the top-level JSON and fails because required Place fields (e.g., name) are nested under results[0].
Codebase Inconsistency
Other HttpAppleMapsGateway methods that return places (e.g., geocode and reverseGeocode) correctly deserialize into PlaceResults.class, indicating lookupPlace is inconsistent with the expected API response shape.
Recommended Fix
Deserialize the response as PlaceResults and return the first result (or throw if empty).
@Override
public Place lookupPlace(String placeId, String language) {
Objects.requireNonNull(placeId, "placeId");
String resolvedLanguage = Objects.requireNonNull(language, "language");
String queryString = "";
if (!resolvedLanguage.isBlank()) {
queryString = QUERY_PREFIX + PARAMETER_LANGUAGE + "=" + resolvedLanguage;
}
PlaceResults response = invokeApi("place", URI.create(API_SERVER + PLACE_PATH + "/" + placeId + queryString), PlaceResults.class); // <-- FIX 🟢
return response.results().stream().findFirst().orElseThrow(() -> new AppleMapsClientException("place", new RuntimeException("Place not found"))); // <-- FIX 🟢
}
History
This bug was introduced in commit 6787139. The original change added the HttpAppleMapsGateway adapter, but it incorrectly attempted to deserialize the singular /v1/place/{id} response directly into a Place record instead of the PlaceResults wrapper returned by the Apple Maps API.
Detail Bug Report
https://app.detail.dev/org_befd6425-a158-4e24-9d4d-1e5c08769515/bugs/bug_4b0dc27e-1a85-46f5-8317-afad12054f54
Summary
AppleMapsGatewayinterface defines methods for interacting with the Apple Maps Server API, including looking up a single place by its identifier.HttpAppleMapsGatewayimplementation, thelookupPlacemethod attempts to deserialize the API response directly into aPlacerecord. However, the Apple Maps Server API always returns aPlaceResultsobject (which contains aresultsarray) even for single-place lookups.Placeobject at the top level of the JSON response, but receives aPlaceResultsobject; this causes aValueInstantiationException(orNullPointerException) because the required fields of thePlacerecord are missing from the top-level JSON.lookupPlacemethod is completely non-functional and will fail whenever it is called against the live Apple Maps Server API.Code with Bug
Explanation
Apple’s Place Lookup endpoint (
GET /v1/place/{id}) returns aPlaceResultswrapper object containing aresultsarray ofPlaceobjects.lookupPlacecurrently requestsPlace.classfrominvokeApi, so Jackson attempts to construct aPlacefrom the top-level JSON and fails because requiredPlacefields (e.g.,name) are nested underresults[0].Codebase Inconsistency
Other
HttpAppleMapsGatewaymethods that return places (e.g.,geocodeandreverseGeocode) correctly deserialize intoPlaceResults.class, indicatinglookupPlaceis inconsistent with the expected API response shape.Recommended Fix
Deserialize the response as
PlaceResultsand return the first result (or throw if empty).History
This bug was introduced in commit 6787139. The original change added the
HttpAppleMapsGatewayadapter, but it incorrectly attempted to deserialize the singular/v1/place/{id}response directly into aPlacerecord instead of thePlaceResultswrapper returned by the Apple Maps API.