diff --git a/.changes/next-release/bugfix-7ebf9104-80a4-452e-a07a-0966078fe077.json b/.changes/next-release/bugfix-7ebf9104-80a4-452e-a07a-0966078fe077.json new file mode 100644 index 00000000000..b47e96060b4 --- /dev/null +++ b/.changes/next-release/bugfix-7ebf9104-80a4-452e-a07a-0966078fe077.json @@ -0,0 +1,4 @@ +{ + "type" : "bugfix", + "description" : "Gracefully handle additional fields in Amazon Q /dev code generation result without throwing errors" +} \ No newline at end of file diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt index b3fd02a890d..3f6e1f52c8b 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt @@ -3,6 +3,7 @@ package software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util +import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.fasterxml.jackson.module.kotlin.readValue import com.intellij.openapi.project.Project @@ -37,6 +38,9 @@ import software.aws.toolkits.telemetry.Result private val logger = getLogger() class FeatureDevService(val proxyClient: FeatureDevClient, val project: Project) { + private val objectMapper = jacksonObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + fun createConversation(): String { val startTime = System.currentTimeMillis() var failureReason: String? = null @@ -238,7 +242,7 @@ class FeatureDevService(val proxyClient: FeatureDevClient, val project: Project) val parsedResult: ExportTaskAssistResultArchiveStreamResult try { val result = exportResponse.reduce { acc, next -> acc + next } // To map the result it is needed to combine the full byte array - parsedResult = jacksonObjectMapper().readValue(result) + parsedResult = objectMapper.readValue(result) } catch (e: Exception) { logger.error(e) { "Failed to parse downloaded code results" } throw ExportParseException(operation = FeatureDevOperation.ExportTaskAssistArchiveResult.toString(), desc = null, e.cause) diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevServiceTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevServiceTest.kt index a49e1e25a41..2cccde2f496 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevServiceTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevServiceTest.kt @@ -351,6 +351,23 @@ class FeatureDevServiceTest : FeatureDevTestBase() { }.isExactlyInstanceOf(ExportParseException::class.java) } + @Test + fun `test exportTaskAssistArchiveResult ignore extra fields in the response`() { + runTest { + val codeGenerationJson = "{" + + "\"code_generation_result\":{\"new_file_contents\":{\"test.ts\":\"contents\"},\"deleted_files\":[],\"references\":[],\"extra_filed\":[]}" + + "}" + + whenever(featureDevClient.exportTaskAssistResultArchive(testConversationId)).thenReturn(mutableListOf(codeGenerationJson.toByteArray())) + + val actual = featureDevService.exportTaskAssistArchiveResult(testConversationId) + assertThat(actual).isInstanceOf(CodeGenerationStreamResult::class.java) + assertThat(actual.new_file_contents).isEqualTo(mapOf(Pair("test.ts", "contents"))) + assertThat(actual.deleted_files).isEqualTo(emptyList()) + assertThat(actual.references).isEqualTo(emptyList()) + } + } + @Test fun `test exportTaskAssistArchiveResult returns correct parsed result`() = runTest {