Когда я создаю клиент с функцией JacksonSerializer() и делаю несколько вызовов API, а затем запускаю этот скрипт на своем локальном компьютере, я не получаю никаких ошибок, и скрипт выполняется успешно. Однако, когда я загружаю этот скрипт как AWS Lambda, я получаю следующую ошибку:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of kotlin.coroutines.Continuation, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
Сначала я подумал, что ошибка возникла из-за того, что я создал клиент вне класса Handler, но когда я сделал клиент частным значением внутри класса Handler, я все равно получаю ошибку. Я включил операторы println() в свою функцию, но они даже не запускаются. Это говорит мне, что моя функция handleRequest() не запускается. Есть ли какой-то AWS/Lambda'изм, который мешает мне использовать функцию JacksonSerializer() как? Если да, есть ли какие-либо альтернативы тому, как анализировать ответы JSON с помощью клиента Ktor?
Моя клиентская конструкция:
private val client = HttpClient(Apache) {
install(JsonFeature) {
serializer = JacksonSerializer()
}
}
Пример вызова с использованием клиента:
val response = client.post<JsonNode> {
url(URL(GITHUB_GRAPHQL_ENDPOINT))
body = reqBody
headers {
append("Authorization", "bearer $token")
}
}





Вы проверили свои зависимости, работающие локально, по сравнению с вашими зависимостями в AWS? У меня были проблемы, когда локально я запускал версию, но версия в AWS была другой. Это могло бы особенно объяснить ошибку с продолжениями... Возможно, сигнатура метода отличается в той версии, которую вы используете?
Особенно ищите provided области в вашем gradle/maven pom. Это легкие места, где версия может быть не синхронизирована.
Я предполагаю, что вы сделали свою функцию обработчика функцией kotlin suspend? Если да, то это ваша проблема.
Когда вы отмечаете функцию suspend, компилятор применяет кучу магии. В большинстве случаев вам не нужно ничего об этом знать, кроме того факта, что любая функция suspend получает дополнительный параметр типа kotlin.coroutines.Continuation, добавленный к ее сигнатуре. Обычно вы этого не замечаете, так как компилятор также заставляет вызовы функции проходить по собственному скрытому параметру Continuation.
Continuation по замыслу не может быть создан таким инструментом как Джексон - это внутреннее дело. Что вам, вероятно, нужно сделать (при условии, что вы создали функцию обработчика suspend), так это обернуть свой метод в runBlocking {} и сделать так, чтобы он не был функцией suspend. Вероятно, проще всего создать новый обработчик, например:
fun fixedHandler(input: MyInput, context: Context) = runBlocking {
originalHandler(input, context)
}
suspend fun originalHandler(input: MyInput, context: Context): MyOutput {
TODO("This is your original code")
}
PS. Обычно я считаю, что для написания моих функций Lambda лучше всего использовать предопределенные интерфейсы Lambda — это предотвращает возникновение подобных проблем. См. https://docs.aws.amazon.com/lambda/latest/dg/java-handler-using-predefined-interfaces.html, как это сделать.