googlemaps / googlemaps/google-maps-services-java

Using Ktor results in CallNotFoundException due to work on wrong thread

Abierto
#672 4 comentarios 0 reacciones 0 asignados Ver en GitHub
triage me type: bug
Lenguaje dominante
Java
Estrellas
1.8k
Forks
973
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

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)
```

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.