JacksonSerializer не работает в Kotlin Lambda

Когда я создаю клиент с функцией 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")
    }
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
266
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы проверили свои зависимости, работающие локально, по сравнению с вашими зависимостями в 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, как это сделать.

Другие вопросы по теме