googlemaps / googlemaps/google-maps-services-java

Using Ktor results in CallNotFoundException due to work on wrong thread

Aperta
#672 4 commenti 0 reazioni 0 assegnatari Vedi su GitHub
triage me type: bug
Lingua principale
Java
Stelle
1.8k
Fork
973
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

I'm using Ktor, which is based on coroutines. This seems to be conflicting with the thread manager that the Google Maps Platform Java library uses. It keeps giving me an `Unexpected exception from com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager` error.

#### Environment details

1. Specify the API at the beginning of the title (for example, "Places: ...")
2. OS type and version
3. Library version and other environment information

Places Autocomplete
Kotlin 1.4
0.11.0
#### Steps to reproduce

1. Make a request to `PlacesApi.placeAutocomplete(context, query, null).await()`

#### Code example
```kotlin
fun Application.placesAutocomplete() {
routing {
get("/v1/places/autocomplete") {
val parameters = call.request.queryParameters
val query: String? = parameters["query"]
val type: String? = parameters["type"]

if (query == null) {
call.respondParameterRequired("query")
return@get
}

if (query.isBlank()) {
call.respond(AutocompleteResponse(emptyList()))
return@get
}

val PLACES_KEY = System.getenv("PLACES_KEY")

val placeAutocompleteTypes = try {
type?.let { PlaceAutocompleteType.valueOf(type) }
} catch (e: IllegalArgumentException) {
call.respond(HttpStatusCode.BadRequest, "Invalid place type")
return@get
}

val context = GeoApiContext.Builder(GaeRequestHandler.Builder()).apiKey(PLACES_KEY).build()

val placeAutocompleteRequest = PlacesApi.placeAutocomplete(context, query, null)
placeAutocompleteTypes?.let { types ->
placeAutocompleteRequest.types(types)
}

try {
val placeAutocompleteResponse = withContext(Dispatchers.IO) { placeAutocompleteRequest.await() }
val places = placeAutocompleteResponse.map {
val formatting = it.structuredFormatting
Place(
placeId = it.placeId, mainText = formatting.mainText
?: "", secondaryText = formatting.secondaryText
?: ""
)
}

val autocompleteResponse = AutocompleteResponse(places)
call.respond(autocompleteResponse)
} catch (e: Exception) {
call.respond(HttpStatusCode.InternalServerError, e)
}
}
}
}
```

#### Stack trace
```
com.google.maps.errors.UnknownErrorException: Unexpected exception from com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call urlfetch.Fetch in a thread that is neither the original request thread nor a thread created by ThreadManager
at com.google.maps.internal.GaePendingResult.await(GaePendingResult.java:121)
at com.google.maps.PendingResultBase.await(PendingResultBase.java:58)
at appengine.PlacesAutocompleteKt$placesAutocomplete$1$1$placeAutocompleteResponse$1.invokeSuspend(PlacesAutocomplete.kt:74)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:272)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:79)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:54)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:36)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at appengine.PlacesAutocompleteKt$placesAutocomplete$1$1.invokeSuspend(PlacesAutocomplete.kt:74)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:175)
at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:137)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:108)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:307)
at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:317)
at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:249)
at retrofit2.KotlinExtensions$awaitResponse$2$2.onResponse(KotlinExtensions.kt:93)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:129)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
```

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.