From b7331793909ae5e74929d4100c45564e807bcc56 Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Wed, 11 Dec 2024 10:29:07 -0800 Subject: [PATCH 01/15] Error handling for UTG --- .../codewhisperer/codetest/sessionconfig/CodeTestException.kt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestException.kt diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestException.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestException.kt new file mode 100644 index 00000000000..c3c8b109694 --- /dev/null +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestException.kt @@ -0,0 +1,2 @@ +package software.aws.toolkits.jetbrains.services.codewhisperer.codetest.sessionconfig + From bc08f99d632a39eb2d863a81c0f6f165ea041937 Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Wed, 11 Dec 2024 10:29:32 -0800 Subject: [PATCH 02/15] Error handling for UTG --- .../CodeWhispererCodeTestSession.kt | 7 +- .../CodeWhispererUTGChatManager.kt | 100 +++++++++++++----- .../controller/CodeTestChatController.kt | 3 +- .../codescan/AmazonQCodeFixSession.kt | 5 +- .../codescan/CodeWhispererCodeScanSession.kt | 9 +- .../sessionconfig/CodeTestException.kt | 2 - .../sessionconfig/CodeTestSessionConfig.kt | 10 +- .../util/CodeWhispererConstants.kt | 5 + .../util/CodeWhispererZipUploadManager.kt | 61 ++++++++--- .../codescan/CodeWhispererCodeFileScanTest.kt | 14 ++- .../codescan/CodeWhispererCodeScanTest.kt | 20 ++-- .../codescan/CodeWhispererCodeScanTestBase.kt | 2 +- .../resources/MessagesBundle.properties | 7 +- 13 files changed, 168 insertions(+), 77 deletions(-) delete mode 100644 plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestException.kt diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererCodeTestSession.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererCodeTestSession.kt index fd075b9756a..f197d48c4a2 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererCodeTestSession.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererCodeTestSession.kt @@ -34,9 +34,6 @@ class CodeWhispererCodeTestSession(val sessionContext: CodeTestSessionContext) { * Run UTG sessions are follow steps: * 1. Zipping project * 2. Creating Upload url & Upload to S3 bucket - * 3. StartTestGeneration API -> Get JobId - * 4. GetTestGeneration API - * 5. ExportResultsArchieve API */ suspend fun run(codeTestChatHelper: CodeTestChatHelper, previousIterationContext: PreviousUTGIterationContext?): CodeTestResponseContext { try { @@ -94,7 +91,8 @@ class CodeWhispererCodeTestSession(val sessionContext: CodeTestSessionContext) { sourceZip, "SourceCode", CodeWhispererConstants.UploadTaskType.UTG, - taskName + taskName, + CodeWhispererConstants.FeatureName.TEST_GENERATION ) sourceZipUploadResponse.uploadId() @@ -113,7 +111,6 @@ class CodeWhispererCodeTestSession(val sessionContext: CodeTestSessionContext) { sourceZipUploadResponse, testSummaryMessageId ) - // TODO send telemetry for upload duration return codeTestResponseContext } catch (e: Exception) { diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt index b2913d66285..d4ba21882fe 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt @@ -16,7 +16,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import software.amazon.awssdk.services.codewhispererruntime.model.CodeWhispererRuntimeException import software.amazon.awssdk.services.codewhispererruntime.model.GetTestGenerationResponse import software.amazon.awssdk.services.codewhispererruntime.model.Range import software.amazon.awssdk.services.codewhispererruntime.model.StartTestGenerationResponse @@ -38,9 +37,14 @@ import software.aws.toolkits.jetbrains.services.amazonqCodeTest.session.BuildAnd import software.aws.toolkits.jetbrains.services.amazonqCodeTest.session.Session import software.aws.toolkits.jetbrains.services.amazonqCodeTest.utils.combineBuildAndExecuteLogFiles import software.aws.toolkits.jetbrains.services.codemodernizer.utils.calculateTotalLatency +import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.CodeTestException +import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.codeTestServerException import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.sessionconfig.CodeTestSessionConfig +import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.testGenStoppedError import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor +import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.promptReAuth +import software.aws.toolkits.jetbrains.services.codewhisperer.util.getTelemetryErrorMessage import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl import software.aws.toolkits.jetbrains.services.cwc.messages.ChatMessageType import software.aws.toolkits.jetbrains.services.cwc.messages.CodeReference @@ -67,7 +71,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin private fun throwIfCancelled(session: Session) { if (!session.isGeneratingTests) { - error(message("testgen.message.cancelled")) + throw testGenStoppedError() } } @@ -104,24 +108,37 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin } // 2nd API call: StartTestGeneration - val startTestGenerationResponse = startTestGeneration( - uploadId = createUploadUrlResponse.uploadId(), - targetCode = listOf( - TargetCode.builder() - .relativeTargetPath(codeTestResponseContext.currentFileRelativePath.toString()) - .targetLineRangeList( - if (selectionRange != null) { - listOf( - selectionRange - ) - } else { - emptyList() - } - ) - .build() - ), - userInput = prompt - ) + val startTestGenerationResponse = try { + startTestGeneration( + uploadId = createUploadUrlResponse.uploadId(), + targetCode = listOf( + TargetCode.builder() + .relativeTargetPath(codeTestResponseContext.currentFileRelativePath.toString()) + .targetLineRangeList( + if (selectionRange != null) { + listOf( + selectionRange + ) + } else { + emptyList() + } + ) + .build() + ), + userInput = prompt + ) + } catch (e: Exception) { + LOG.error(e) { "Failed to create test generation job" } + // TODO: Not able to emit e.statusCode directly as statusCode is private property + // Cannot access 'statusCode': it is invisible (private in a supertype) in 'ThrottlingException' + val errorMessage = getTelemetryErrorMessage(e, CodeWhispererConstants.FeatureName.TEST_GENERATION) + throw codeTestServerException( + "CreateTestJobError: $errorMessage", + "400", + "CreateTestJobError", + message("testgen.error.generic_technical_error_message") + ) + } val job = startTestGenerationResponse.testGenerationJob() session.startTestGenerationRequestId = startTestGenerationResponse.responseMetadata().requestId() @@ -173,7 +190,13 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin } // update test summary card } else { - throw Exception(message("testgen.message.failed")) + // If job status is Completed and has no ShortAnswer then there might be some issue in the backend. + throw codeTestServerException( + "TestGenFailedError: " + message("testgen.message.failed"), + "500", + "TestGenFailedError", + message("testgen.error.generic_technical_error_message") + ) } } else if (status == TestGenerationJobStatus.FAILED) { LOG.debug { @@ -184,11 +207,17 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin shortAnswer = parseShortAnswerString(testGenerationResponse.testGenerationJob().shortAnswer()) if (shortAnswer.stopIteration == "true") { throw Exception("${shortAnswer.planSummary}") + throw codeTestServerException("TestGenFailedError: ${shortAnswer.planSummary}", "400", "TestGenFailedError", shortAnswer.planSummary) } } - // TODO: Modify text according to FnF - throw Exception(message("testgen.message.failed")) + // If job status is Failed and has no ShortAnswer then there might be some issue in the backend. + throw codeTestServerException( + "TestGenFailedError: " + message("testgen.message.failed"), + "500", + "TestGenFailedError", + message("testgen.error.generic_technical_error_message") + ) } else { // In progress LOG.debug { @@ -200,7 +229,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin if (previousIterationContext == null && testGenerationResponse.testGenerationJob().shortAnswer() != null) { shortAnswer = parseShortAnswerString(testGenerationResponse.testGenerationJob().shortAnswer()) if (shortAnswer.stopIteration == "true") { - throw Exception("${shortAnswer.planSummary}") + throw codeTestServerException("TestGenFailedError: ${shortAnswer.planSummary}", "400", "TestGenFailedError", shortAnswer.planSummary) } codeTestChatHelper.updateAnswer( CodeTestChatMessageContent( @@ -232,6 +261,12 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin }, { e -> LOG.error(e) { "ExportResultArchive failed: ${e.message}" } + throw codeTestServerException( + "ExportResultsArchiveError: ${e.message}", + "500", + "ExportResultsArchiveError", + message("testgen.error.generic_technical_error_message") + ) }, { startTime -> LOG.info { "ExportResultArchive latency: ${calculateTotalLatency(startTime, Instant.now())}" } @@ -495,10 +530,18 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin // Add an answer for displaying error message var errorMessage = e.message if (e is JsonParseException) { - errorMessage = message("testgen.error.generic_error_message") + errorMessage = message("testgen.error.generic_technical_error_message") + } + if (e is CodeTestException) { + errorMessage = e.uiMessage } - if (e is CodeWhispererRuntimeException) { + if (e is CodeTestException && e.statusCode == "400" && + e.message?.startsWith( + "CreateTestJobError: Maximum com.amazon.aws.codewhisperer.runtime.StartTestGeneration " + + "reached for this month." + ) != false + ) { errorMessage = message("testgen.error.maximum_generations_reach") } codeTestChatHelper.addAnswer( @@ -517,8 +560,9 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin jobGroup = session.testGenerationJobGroupName, jobId = session.testGenerationJob, result = if (e.message == message("testgen.message.cancelled")) MetricResult.Cancelled else MetricResult.Failed, - reason = e.javaClass.name, - reasonDesc = e.message, + reason = (e as CodeTestException).code ?: "DefaultError", + reasonDesc = if (e.message == message("testgen.message.cancelled")) "${e.code}: ${e.message}" else e.message, + httpStatusCode = e.statusCode ?: "400", perfClientLatency = (Instant.now().toEpochMilli() - session.startTimeOfTestGeneration), isCodeBlockSelected = session.isCodeBlockSelected, artifactsUploadDuration = session.artifactUploadDuration, diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt index eba7f1334c5..d478407d691 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt @@ -291,7 +291,8 @@ class CodeTestChatController( credentialStartUrl = getStartUrl(project), result = MetricResult.Succeeded, perfClientLatency = (Instant.now().toEpochMilli() - session.startTimeOfTestGeneration), - requestId = id + requestId = id, + httpStatusCode = "200" ) } session.isGeneratingTests = false diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/AmazonQCodeFixSession.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/AmazonQCodeFixSession.kt index 9fa5b022953..a1452f74cfa 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/AmazonQCodeFixSession.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/AmazonQCodeFixSession.kt @@ -72,7 +72,8 @@ class AmazonQCodeFixSession(val project: Project) { sourceZip, "SourceCode", CodeWhispererConstants.UploadTaskType.CODE_FIX, - codeFixName + codeFixName, + CodeWhispererConstants.FeatureName.CODE_REVIEW ) /** @@ -149,7 +150,7 @@ class AmazonQCodeFixSession(val project: Project) { ) } catch (e: Exception) { LOG.debug { "Create Upload URL failed: ${e.message}" } - val errorMessage = getTelemetryErrorMessage(e) + val errorMessage = getTelemetryErrorMessage(e, featureUseCase = CodeWhispererConstants.FeatureName.CODE_REVIEW) throw codeScanServerException("CreateUploadUrlException: $errorMessage") } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt index 4257e91100f..2550d830e41 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt @@ -117,7 +117,8 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { sourceZip, "SourceCode", taskType, - codeScanName + codeScanName, + CodeWhispererConstants.FeatureName.CODE_REVIEW ) if (isProjectScope()) { LOG.debug { @@ -272,7 +273,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { ) } catch (e: Exception) { LOG.debug { "Creating code review failed: ${e.message}" } - val errorMessage = getTelemetryErrorMessage(e) + val errorMessage = getTelemetryErrorMessage(e, featureUseCase = CodeWhispererConstants.FeatureName.CODE_REVIEW) throw codeScanServerException(errorMessage) } } @@ -285,7 +286,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { ) } catch (e: Exception) { LOG.debug { "Getting code review failed: ${e.message}" } - val errorMessage = getTelemetryErrorMessage(e) + val errorMessage = getTelemetryErrorMessage(e, featureUseCase = CodeWhispererConstants.FeatureName.CODE_REVIEW) throw codeScanServerException("GetCodeReviewException: $errorMessage") } @@ -299,7 +300,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { ) } catch (e: Exception) { LOG.debug { "Listing code review failed: ${e.message}" } - val errorMessage = getTelemetryErrorMessage(e) + val errorMessage = getTelemetryErrorMessage(e, featureUseCase = CodeWhispererConstants.FeatureName.CODE_REVIEW) throw codeScanServerException("ListCodeReviewFindingsException: $errorMessage") } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestException.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestException.kt deleted file mode 100644 index c3c8b109694..00000000000 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestException.kt +++ /dev/null @@ -1,2 +0,0 @@ -package software.aws.toolkits.jetbrains.services.codewhisperer.codetest.sessionconfig - diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt index fcd2fbfcabe..f256df921d3 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt @@ -19,13 +19,13 @@ import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.putNextEntry import software.aws.toolkits.jetbrains.services.amazonq.FeatureDevSessionContext -import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.cannotFindBuildArtifacts -import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.cannotFindFile -import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.fileTooLarge -import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.noFileOpenError import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.sessionconfig.Payload import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.sessionconfig.PayloadContext import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.sessionconfig.PayloadMetadata +import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.cannotFindBuildArtifacts +import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.cannotFindFile +import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.fileTooLarge +import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.noFileOpenError import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererUnknownLanguage import software.aws.toolkits.jetbrains.services.codewhisperer.language.programmingLanguage @@ -94,7 +94,7 @@ class CodeTestSessionConfig( else -> e.message } LOG.debug { "Error creating payload metadata: $errorMessage" } - throw cannotFindBuildArtifacts(errorMessage ?: message("codewhisperer.codescan.run_scan_error_telemetry")) + throw cannotFindBuildArtifacts(errorMessage ?: message("testgen.message.failed")) } // Copy all the included source files to the source zip diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt index 1472d88f9eb..a56e5e0270c 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt @@ -127,6 +127,11 @@ object CodeWhispererConstants { PROJECT("PROJECT"), } + enum class FeatureName(val value: String) { + TEST_GENERATION("TEST_GENERATION"), + CODE_REVIEW("CODE_REVIEW"), + } + enum class UploadTaskType(val value: String) { SCAN_FILE("SCAN_FILE"), SCAN_PROJECT("SCAN_PROJECT"), diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererZipUploadManager.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererZipUploadManager.kt index ce31a86f713..04d9bed768e 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererZipUploadManager.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererZipUploadManager.kt @@ -25,7 +25,9 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhisp import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanSession.Companion.SERVER_SIDE_ENCRYPTION import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanSession.Companion.SERVER_SIDE_ENCRYPTION_AWS_KMS_KEY_ID import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanSession.Companion.SERVER_SIDE_ENCRYPTION_CONTEXT +import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.codeScanServerException import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.invalidSourceZipError +import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.codeTestServerException import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor import software.aws.toolkits.resources.message import java.io.File @@ -33,6 +35,7 @@ import java.io.FileInputStream import java.io.IOException import java.net.HttpURLConnection import java.util.Base64 +import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.invalidSourceZipError as testGenerationInvalidSourceZipError @Service class CodeWhispererZipUploadManager(private val project: Project) { @@ -42,16 +45,20 @@ class CodeWhispererZipUploadManager(private val project: Project) { artifactType: String, taskType: CodeWhispererConstants.UploadTaskType, taskName: String, + featureUseCase: CodeWhispererConstants.FeatureName, ): CreateUploadUrlResponse { // Throw error if zipFile is invalid. if (!zipFile.exists()) { - invalidSourceZipError() + when (featureUseCase) { + CodeWhispererConstants.FeatureName.CODE_REVIEW -> invalidSourceZipError() + CodeWhispererConstants.FeatureName.TEST_GENERATION -> testGenerationInvalidSourceZipError() + else -> throw IllegalArgumentException("Unsupported feature case: $featureUseCase") // Adding else for safety check + } } val fileMd5: String = Base64.getEncoder().encodeToString(DigestUtils.md5(FileInputStream(zipFile))) - val createUploadUrlResponse = createUploadUrl(fileMd5, artifactType, taskType, taskName) + val createUploadUrlResponse = createUploadUrl(fileMd5, artifactType, taskType, taskName, featureUseCase) val url = createUploadUrlResponse.uploadUrl() - - LOG.debug { "Uploading $artifactType using the presigned URL." } + LOG.debug { "$featureUseCase: Uploading $artifactType using the presigned URL." } uploadArtifactToS3( url, @@ -59,7 +66,8 @@ class CodeWhispererZipUploadManager(private val project: Project) { zipFile, fileMd5, createUploadUrlResponse.kmsKeyArn(), - createUploadUrlResponse.requestHeaders() + createUploadUrlResponse.requestHeaders(), + featureUseCase ) return createUploadUrlResponse } @@ -72,6 +80,7 @@ class CodeWhispererZipUploadManager(private val project: Project) { md5: String, kmsArn: String?, requestHeaders: Map?, + featureUseCase: CodeWhispererConstants.FeatureName, ) { try { val uploadIdJson = """{"uploadId":"$uploadId"}""" @@ -95,9 +104,18 @@ class CodeWhispererZipUploadManager(private val project: Project) { IoUtils.copy(fileToUpload.inputStream(), connection.outputStream) } } catch (e: Exception) { - LOG.debug { "Artifact failed to upload in the S3 bucket: ${e.message}" } - val errorMessage = getTelemetryErrorMessage(e) - throw RuntimeException(errorMessage) + LOG.debug { "$featureUseCase: Artifact failed to upload in the S3 bucket: ${e.message}" } + val errorMessage = getTelemetryErrorMessage(e, featureUseCase) + when (featureUseCase) { + CodeWhispererConstants.FeatureName.CODE_REVIEW -> throw codeScanServerException("CreateUploadUrlException: $errorMessage") + CodeWhispererConstants.FeatureName.TEST_GENERATION -> throw codeTestServerException( + "UploadTestArtifactToS3Error: $errorMessage", + "403", + "UploadTestArtifactToS3Error", + message("testgen.error.generic_technical_error_message") + ) + else -> throw RuntimeException(errorMessage) // Adding else for safety check + } } } @@ -106,6 +124,7 @@ class CodeWhispererZipUploadManager(private val project: Project) { artifactType: String, uploadTaskType: CodeWhispererConstants.UploadTaskType, taskName: String, + featureUseCase: CodeWhispererConstants.FeatureName, ): CreateUploadUrlResponse = try { CodeWhispererClientAdaptor.getInstance(project).createUploadUrl( CreateUploadUrlRequest.builder() @@ -113,6 +132,7 @@ class CodeWhispererZipUploadManager(private val project: Project) { .artifactType(artifactType) .uploadIntent(getUploadIntent(uploadTaskType)) .uploadContext( + // For UTG we don't need uploadContext but sending else case as UploadContext if (uploadTaskType == CodeWhispererConstants.UploadTaskType.CODE_FIX) { UploadContext.fromCodeFixUploadContext(CodeFixUploadContext.builder().codeFixName(taskName).build()) } else { @@ -122,9 +142,18 @@ class CodeWhispererZipUploadManager(private val project: Project) { .build() ) } catch (e: Exception) { - LOG.debug { "Create Upload URL failed: ${e.message}" } - val errorMessage = getTelemetryErrorMessage(e) - throw RuntimeException(errorMessage) + LOG.debug { "$featureUseCase: Create Upload URL failed: ${e.message}" } + val errorMessage = getTelemetryErrorMessage(e, featureUseCase) + when (featureUseCase) { + CodeWhispererConstants.FeatureName.CODE_REVIEW -> throw codeScanServerException("CreateUploadUrlException: $errorMessage") + CodeWhispererConstants.FeatureName.TEST_GENERATION -> throw codeTestServerException( + "CreateUploadUrlError: $errorMessage", + "500", + "CreateUploadUrlError", + message("testgen.error.generic_technical_error_message") + ) + else -> throw RuntimeException(errorMessage) // Adding else for safety check + } } private fun getUploadIntent(uploadTaskType: CodeWhispererConstants.UploadTaskType): UploadIntent = when (uploadTaskType) { @@ -140,17 +169,23 @@ class CodeWhispererZipUploadManager(private val project: Project) { } } -fun getTelemetryErrorMessage(e: Exception): String = when { +fun getTelemetryErrorMessage(e: Exception, featureUseCase: CodeWhispererConstants.FeatureName): String = when { e.message?.contains("Resource not found.") == true -> "Resource not found." e.message?.contains("Maximum com.amazon.aws.codewhisperer.StartCodeAnalysis reached for this month.") == true -> message( "testgen.error.maximum_generations_reach" ) + e.message?.contains("Maximum com.amazon.aws.codewhisperer.runtime.StartTestGeneration reached for this month.") == true + -> "Maximum com.amazon.aws.codewhisperer.runtime.StartTestGeneration reached for this month." e.message?.contains("Service returned HTTP status code 407") == true -> "Service returned HTTP status code 407" e.message?.contains("Improperly formed request") == true -> "Improperly formed request" e.message?.contains("Service returned HTTP status code 403") == true -> "Service returned HTTP status code 403" + e.message?.contains("Service returned HTTP status code 503") == true -> "Service returned HTTP status code 503" e.message?.contains("invalid_grant: Invalid token provided") == true -> "invalid_grant: Invalid token provided" e.message?.contains("Connect timed out") == true -> "Unable to execute HTTP request: Connect timed out" // Error: Connect to host failed e.message?.contains("Encountered an unexpected error when processing the request, please try again.") == true -> "Encountered an unexpected error when processing the request, please try again." - else -> e.message ?: message("codewhisperer.codescan.run_scan_error_telemetry") + else -> e.message ?: when (featureUseCase) { + CodeWhispererConstants.FeatureName.CODE_REVIEW -> message("codewhisperer.codescan.run_scan_error_telemetry") + else -> message("testgen.message.failed") + } } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt index 20c4c2d2d4b..a39164933e5 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt @@ -229,7 +229,7 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn val file = pyPsiFile.virtualFile.toNioPath().toFile() val fileMd5: String = Base64.getEncoder().encodeToString(DigestUtils.md5(FileInputStream(file))) zipUploadManagerSpy.stub { - onGeneric { zipUploadManagerSpy.createUploadUrl(any(), any(), any(), any()) } + onGeneric { zipUploadManagerSpy.createUploadUrl(any(), any(), any(), any(), any()) } .thenReturn(fakeCreateUploadUrlResponse) } @@ -237,7 +237,8 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn file, "artifactType", CodeWhispererConstants.UploadTaskType.SCAN_FILE, - codeScanName + codeScanName, + CodeWhispererConstants.FeatureName.CODE_REVIEW ) val inOrder = inOrder(zipUploadManagerSpy) @@ -245,6 +246,7 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn eq(fileMd5), eq("artifactType"), eq(CodeWhispererConstants.UploadTaskType.SCAN_FILE), + any(), any() ) inOrder.verify(zipUploadManagerSpy).uploadArtifactToS3( @@ -253,6 +255,7 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn eq(file), eq(fileMd5), eq(null), + any(), any() ) } @@ -263,7 +266,8 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn "md5", "type", CodeWhispererConstants.UploadTaskType.SCAN_FILE, - codeScanName + codeScanName, + CodeWhispererConstants.FeatureName.CODE_REVIEW ) argumentCaptor().apply { @@ -297,7 +301,7 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn assertThat(it.responseContext.codeScanJobId).isEqualTo("jobId") } - verify(zipUploadManagerSpy, times(1)).createUploadUrlAndUpload(eq(file), eq("SourceCode"), any(), anyString()) + verify(zipUploadManagerSpy, times(1)).createUploadUrlAndUpload(eq(file), eq("SourceCode"), any(), anyString(), any()) val inOrder = inOrder(codeScanSessionSpy) inOrder.verify(codeScanSessionSpy, times(1)).createCodeScan(eq(CodewhispererLanguage.Python.toString()), anyString()) inOrder.verify(codeScanSessionSpy, times(1)).getCodeScan(any()) @@ -360,7 +364,7 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn assertNotNull(pySession) mockClient.stub { - onGeneric { zipUploadManagerSpy.createUploadUrlAndUpload(any(), any(), any(), any()) }.thenThrow( + onGeneric { zipUploadManagerSpy.createUploadUrlAndUpload(any(), any(), any(), any(), any()) }.thenThrow( CodeWhispererException.builder() .message("File Scan Monthly Exceeded") .requestId("abc123") diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt index 976e7dcf216..de232778dab 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt @@ -95,7 +95,7 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh fun `test createUploadUrlAndUpload()`() { val fileMd5: String = Base64.getEncoder().encodeToString(DigestUtils.md5(FileInputStream(file))) zipUploadManagerSpy.stub { - onGeneric { zipUploadManagerSpy.createUploadUrl(any(), any(), any(), any()) } + onGeneric { zipUploadManagerSpy.createUploadUrl(any(), any(), any(), any(), any()) } .thenReturn(fakeCreateUploadUrlResponse) } @@ -103,17 +103,19 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh file, "artifactType", CodeWhispererConstants.UploadTaskType.SCAN_FILE, - codeScanName + codeScanName, + CodeWhispererConstants.FeatureName.CODE_REVIEW ) val inOrder = inOrder(zipUploadManagerSpy) - inOrder.verify(zipUploadManagerSpy).createUploadUrl(eq(fileMd5), eq("artifactType"), any(), any()) + inOrder.verify(zipUploadManagerSpy).createUploadUrl(eq(fileMd5), eq("artifactType"), any(), any(), any()) inOrder.verify(zipUploadManagerSpy).uploadArtifactToS3( eq(fakeCreateUploadUrlResponse.uploadUrl()), eq(fakeCreateUploadUrlResponse.uploadId()), eq(file), eq(fileMd5), eq(null), + any(), any() ) } @@ -127,7 +129,8 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh invalidZipFile, "artifactType", CodeWhispererConstants.UploadTaskType.SCAN_FILE, - codeScanName + codeScanName, + CodeWhispererConstants.FeatureName.CODE_REVIEW ) } } @@ -138,7 +141,8 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh "md5", "type", CodeWhispererConstants.UploadTaskType.SCAN_FILE, - codeScanName + codeScanName, + featureUseCase = CodeWhispererConstants.FeatureName.CODE_REVIEW ) argumentCaptor().apply { @@ -194,7 +198,7 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh ) exceptions.forEachIndexed { index, exception -> - val actualMessage = getTelemetryErrorMessage(exception) + val actualMessage = getTelemetryErrorMessage(exception, featureUseCase = CodeWhispererConstants.FeatureName.CODE_REVIEW) assertThat(expectedMessages[index]).isEqualTo(actualMessage) } } @@ -209,7 +213,7 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh assertThat(it.responseContext.codeScanJobId).isEqualTo("jobId") } - verify(zipUploadManagerSpy, times(1)).createUploadUrlAndUpload(eq(file), eq("SourceCode"), any(), anyString()) + verify(zipUploadManagerSpy, times(1)).createUploadUrlAndUpload(eq(file), eq("SourceCode"), any(), anyString(), any()) val inOrder = inOrder(codeScanSessionSpy) inOrder.verify(codeScanSessionSpy, Times(1)).createCodeScan(eq(CodewhispererLanguage.Python.toString()), anyString()) inOrder.verify(codeScanSessionSpy, Times(1)).getCodeScan(any()) @@ -221,7 +225,7 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh assertNotNull(sessionConfigSpy) mockClient.stub { - onGeneric { zipUploadManagerSpy.createUploadUrlAndUpload(any(), any(), any(), any()) }.thenThrow( + onGeneric { zipUploadManagerSpy.createUploadUrlAndUpload(any(), any(), any(), any(), any()) }.thenThrow( CodeWhispererException.builder() .message("Project Review Monthly Exceeded") .requestId("abc123") diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTestBase.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTestBase.kt index ce295abadfd..ba486c97d5e 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTestBase.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTestBase.kt @@ -109,7 +109,7 @@ open class CodeWhispererCodeScanTestBase(projectRule: CodeInsightTestFixtureRule doNothing().whenever(scanManagerSpy).showCodeScanUI() zipUploadManagerSpy = spy(CodeWhispererZipUploadManager.getInstance(project)) - doNothing().whenever(zipUploadManagerSpy).uploadArtifactToS3(any(), any(), any(), any(), isNull(), any()) + doNothing().whenever(zipUploadManagerSpy).uploadArtifactToS3(any(), any(), any(), any(), isNull(), any(), any()) projectRule.project.replaceService(CodeWhispererZipUploadManager::class.java, zipUploadManagerSpy, disposableRule.disposable) mockClient = mock().also { diff --git a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index 9d683cac640..0fbc0189b62 100644 --- a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -2042,16 +2042,17 @@ sqs.subscribe.sns.validation.empty_topic=Topic must be specified. sqs.toolwindow=SQS sqs.url.parse_error=Error parsing SQS queue URL tags.title=Tags -testgen.error.generic_error_message=I am experiencing technical difficulties at the moment. Please try again in a few minutes. +testgen.error.generic_error_message=Amazon Q encountered an error while generating tests. Try again later. +testgen.error.generic_technical_error_message=I am experiencing technical difficulties at the moment. Please try again in a few minutes. testgen.error.maximum_generations_reach=You've reached the monthly quota for Amazon Q Developer's agent capabilities. You can try again next month. For more information on usage limits, see the Amazon Q Developer pricing page. testgen.message.cancelled=Unit test generation cancelled. testgen.message.failed=Sorry, Test generation failed. Please try again in few minutes. testgen.message.regenerate_input=Sure thing. Please provide new instructions for me to generate the tests, and select the function(s) you would like to test. testgen.message.success=Unit test generation completed. -testgen.no_file_found=Sorry, I couldn't find a file to generate tests. +testgen.no_file_found=Sorry, there isn't a source file open right now that I can generate a test for. Make sure you open a source file so I can generate tests. testgen.placeholder.newtab=Ask any coding question or type \u0022/\u0022 for actions testgen.placeholder.select_an_option = Please select an action to proceed (Accept or Reject) -testgen.placeholder.view_diff="Select View Diff to see the generated unit tests" +testgen.placeholder.view_diff=Select View Diff to see the generated unit tests testgen.placeholder.waiting_on_your_inputs=Waiting on your inputs... testgen.progressbar.generate_unit_tests=Generating unit tests... toolkit.login.aws_builder_id.already_connected.cancel=Use existing AWS Builder ID From c04de5ec60c1929d0377d4288f2235142eac9c22 Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Wed, 11 Dec 2024 18:44:13 -0800 Subject: [PATCH 03/15] Minor edits addresing comments --- .../CodeWhispererUTGChatManager.kt | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt index d4ba21882fe..c60ddd8547c 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt @@ -528,22 +528,16 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin launchTestGenFlow(prompt, codeTestChatHelper, previousIterationContext, selectionRange) } catch (e: Exception) { // Add an answer for displaying error message - var errorMessage = e.message - if (e is JsonParseException) { - errorMessage = message("testgen.error.generic_technical_error_message") - } - if (e is CodeTestException) { - errorMessage = e.uiMessage + val errorMessage = when { + e is CodeTestException && e.statusCode == "400" && + e.message?.startsWith("CreateTestJobError: Maximum com.amazon.aws.codewhisperer.runtime.StartTestGeneration reached for this month.") == true -> + message("testgen.error.maximum_generations_reach") + + e is CodeTestException -> e.uiMessage + e is JsonParseException -> message("testgen.error.generic_technical_error_message") + else -> e.message } - if (e is CodeTestException && e.statusCode == "400" && - e.message?.startsWith( - "CreateTestJobError: Maximum com.amazon.aws.codewhisperer.runtime.StartTestGeneration " + - "reached for this month." - ) != false - ) { - errorMessage = message("testgen.error.maximum_generations_reach") - } codeTestChatHelper.addAnswer( CodeTestChatMessageContent( message = errorMessage, From b22eca6c3324e6d733ef8e92ca3818130e5c256b Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Thu, 12 Dec 2024 06:54:07 -0800 Subject: [PATCH 04/15] Lint errors --- .../services/amazonqCodeTest/CodeWhispererUTGChatManager.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt index c60ddd8547c..3ef8c15ac21 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt @@ -530,7 +530,10 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin // Add an answer for displaying error message val errorMessage = when { e is CodeTestException && e.statusCode == "400" && - e.message?.startsWith("CreateTestJobError: Maximum com.amazon.aws.codewhisperer.runtime.StartTestGeneration reached for this month.") == true -> + e.message?.startsWith( + "CreateTestJobError: " + + "Maximum com.amazon.aws.codewhisperer.runtime.StartTestGeneration reached for this month." + ) == true -> message("testgen.error.maximum_generations_reach") e is CodeTestException -> e.uiMessage From 75a62540844e2261684e0e18ee5561f19f3be148 Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:57:35 -0800 Subject: [PATCH 05/15] Fixing build failures --- .../services/amazonqCodeTest/CodeWhispererCodeTestSession.kt | 2 +- .../codetest/sessionconfig/CodeTestSessionConfig.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererCodeTestSession.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererCodeTestSession.kt index f197d48c4a2..127106f9cd7 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererCodeTestSession.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererCodeTestSession.kt @@ -114,7 +114,7 @@ class CodeWhispererCodeTestSession(val sessionContext: CodeTestSessionContext) { return codeTestResponseContext } catch (e: Exception) { - LOG.debug(e) { "Error when creating tests for the current file" } + LOG.debug(e) { "Error while creating zip and uploading to S3" } throw e } } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt index f256df921d3..542abae566b 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt @@ -24,6 +24,7 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.sessionco import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.sessionconfig.PayloadMetadata import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.cannotFindBuildArtifacts import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.cannotFindFile +import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.cannotFindValidFile import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.fileTooLarge import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.noFileOpenError import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage @@ -218,7 +219,7 @@ class CodeTestSessionConfig( if (maxCountLanguage == null) { programmingLanguage = CodeWhispererUnknownLanguage.INSTANCE - throw RuntimeException("Amazon Q: doesn't contain valid files to generate tests") + throw cannotFindValidFile("Amazon Q: doesn't contain valid files to generate tests") } programmingLanguage = maxCountLanguage return PayloadMetadata(files, currentTotalFileSize, currentTotalLines, maxCountLanguage.toTelemetryType()) From 3a87313f39eb79f0283e06cc58c9eb39318e144e Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:58:16 -0800 Subject: [PATCH 06/15] Fixing build failures --- .../codetest/CodeTestException.kt | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt new file mode 100644 index 00000000000..36915f95341 --- /dev/null +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt @@ -0,0 +1,48 @@ +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.codewhisperer.codetest + +import software.aws.toolkits.resources.message + +open class CodeTestException( + override val message: String?, + val statusCode: String? = "400", + val code: String? = "DefaultError", + val uiMessage: String? = message( + "testgen.error.generic_error_message" + ), +) : RuntimeException() + +open class CodeTestServerException( + override val message: String?, + val statusCode: String? = "400", + val code: String? = "DefaultError", + val uiMessage: String? = message( + "testgen.error.generic_technical_error_message" + ), +) : RuntimeException() + +internal fun noFileOpenError(): Nothing = + throw CodeTestException(message("codewhisperer.codescan.no_file_open"), "400", "ProjectZipError") + +internal fun fileTooLarge(): Nothing = + throw CodeTestException(message("codewhisperer.codescan.file_too_large_telemetry"), "400", "ProjectZipError") + +internal fun cannotFindFile(errorMessage: String, filepath: String): Nothing = + error(message("codewhisperer.codescan.file_not_found", filepath, errorMessage)) + +internal fun cannotFindValidFile(errorMessage: String): Nothing = + throw CodeTestException(errorMessage, "400", "ProjectZipError") + +internal fun cannotFindBuildArtifacts(errorMessage: String): Nothing = + throw CodeTestException(errorMessage, "400", "ProjectZipError") + +internal fun invalidSourceZipError(): Nothing = + throw CodeTestException(message("codewhisperer.codescan.invalid_source_zip_telemetry"), "400", "InvalidSourceZipError") + +fun codeTestServerException(errorMessage: String, statusCode: String?, code: String?, uiMessage: String?): Nothing = + throw CodeTestServerException(errorMessage, statusCode, code, uiMessage) + +fun testGenStoppedError(): Nothing = + throw CodeTestException(message("testgen.message.cancelled"), "400", "TestGenCancelled", message("testgen.message.cancelled")) From 143c8c7a8e7111aa8eb9e7b85cbc2744cff80d4b Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:33:11 -0800 Subject: [PATCH 07/15] Removing CodeTestServerException from CodeTestException file --- .../CodeWhispererUTGChatManager.kt | 5 +---- .../codetest/CodeTestException.kt | 20 +++++++++---------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt index 3ef8c15ac21..81ddc9c661f 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt @@ -530,10 +530,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin // Add an answer for displaying error message val errorMessage = when { e is CodeTestException && e.statusCode == "400" && - e.message?.startsWith( - "CreateTestJobError: " + - "Maximum com.amazon.aws.codewhisperer.runtime.StartTestGeneration reached for this month." - ) == true -> + e.message?.startsWith("CreateTestJobError: Maximum") == true -> message("testgen.error.maximum_generations_reach") e is CodeTestException -> e.uiMessage diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt index 36915f95341..1fd2e756aa7 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt @@ -14,15 +14,6 @@ open class CodeTestException( ), ) : RuntimeException() -open class CodeTestServerException( - override val message: String?, - val statusCode: String? = "400", - val code: String? = "DefaultError", - val uiMessage: String? = message( - "testgen.error.generic_technical_error_message" - ), -) : RuntimeException() - internal fun noFileOpenError(): Nothing = throw CodeTestException(message("codewhisperer.codescan.no_file_open"), "400", "ProjectZipError") @@ -41,8 +32,15 @@ internal fun cannotFindBuildArtifacts(errorMessage: String): Nothing = internal fun invalidSourceZipError(): Nothing = throw CodeTestException(message("codewhisperer.codescan.invalid_source_zip_telemetry"), "400", "InvalidSourceZipError") -fun codeTestServerException(errorMessage: String, statusCode: String?, code: String?, uiMessage: String?): Nothing = - throw CodeTestServerException(errorMessage, statusCode, code, uiMessage) +fun codeTestServerException( + errorMessage: String, + statusCode: String?, + code: String? = "DefaultError", + uiMessage: String? = message( + "testgen.error.generic_technical_error_message" + ), +): Nothing = + throw CodeTestException(errorMessage, statusCode, code, uiMessage) fun testGenStoppedError(): Nothing = throw CodeTestException(message("testgen.message.cancelled"), "400", "TestGenCancelled", message("testgen.message.cancelled")) From d893719733fa3b68d67d559283e52d177e7fe558 Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:42:15 -0800 Subject: [PATCH 08/15] Adding Generic error message for CX facing UX --- .../services/amazonqCodeTest/CodeWhispererUTGChatManager.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt index 81ddc9c661f..c253e37ae59 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt @@ -535,7 +535,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin e is CodeTestException -> e.uiMessage e is JsonParseException -> message("testgen.error.generic_technical_error_message") - else -> e.message + else -> message("testgen.error.generic_error_message") } codeTestChatHelper.addAnswer( From 46985904c17bd55fa89bbca8019551de1e47d1b8 Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:14:21 -0800 Subject: [PATCH 09/15] Changing status code from 4XX to 5XX for CreateTestJobError --- .../services/amazonqCodeTest/CodeWhispererUTGChatManager.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt index c253e37ae59..7176004c789 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt @@ -134,7 +134,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin val errorMessage = getTelemetryErrorMessage(e, CodeWhispererConstants.FeatureName.TEST_GENERATION) throw codeTestServerException( "CreateTestJobError: $errorMessage", - "400", + "500", "CreateTestJobError", message("testgen.error.generic_technical_error_message") ) From a0c6fc1cb37731323b1f252edc91b58c60177525 Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:56:52 -0800 Subject: [PATCH 10/15] Moving statusCode datatype from string to int --- .../CodeWhispererUTGChatManager.kt | 36 ++++++++++--------- .../controller/CodeTestChatController.kt | 6 ++-- .../codetest/CodeTestException.kt | 16 ++++----- .../sessionconfig/CodeTestSessionConfig.kt | 4 +-- .../util/CodeWhispererZipUploadManager.kt | 12 +++---- 5 files changed, 39 insertions(+), 35 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt index 7176004c789..d6b51ad090e 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeWhispererUTGChatManager.kt @@ -21,6 +21,7 @@ import software.amazon.awssdk.services.codewhispererruntime.model.Range import software.amazon.awssdk.services.codewhispererruntime.model.StartTestGenerationResponse import software.amazon.awssdk.services.codewhispererruntime.model.TargetCode import software.amazon.awssdk.services.codewhispererruntime.model.TestGenerationJobStatus +import software.amazon.awssdk.services.codewhispererruntime.model.ThrottlingException import software.amazon.awssdk.services.codewhispererstreaming.model.ExportContext import software.amazon.awssdk.services.codewhispererstreaming.model.ExportIntent import software.aws.toolkits.core.utils.debug @@ -71,7 +72,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin private fun throwIfCancelled(session: Session) { if (!session.isGeneratingTests) { - throw testGenStoppedError() + testGenStoppedError() } } @@ -128,13 +129,15 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin userInput = prompt ) } catch (e: Exception) { - LOG.error(e) { "Failed to create test generation job" } - // TODO: Not able to emit e.statusCode directly as statusCode is private property - // Cannot access 'statusCode': it is invisible (private in a supertype) in 'ThrottlingException' + val statusCode = when { + e is ThrottlingException -> e.statusCode() + else -> 500 + } + LOG.error(e) { "Unexpected error while creating test generation job" } val errorMessage = getTelemetryErrorMessage(e, CodeWhispererConstants.FeatureName.TEST_GENERATION) - throw codeTestServerException( + codeTestServerException( "CreateTestJobError: $errorMessage", - "500", + statusCode, "CreateTestJobError", message("testgen.error.generic_technical_error_message") ) @@ -191,9 +194,9 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin // update test summary card } else { // If job status is Completed and has no ShortAnswer then there might be some issue in the backend. - throw codeTestServerException( + codeTestServerException( "TestGenFailedError: " + message("testgen.message.failed"), - "500", + 500, "TestGenFailedError", message("testgen.error.generic_technical_error_message") ) @@ -206,15 +209,14 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin if (testGenerationResponse.testGenerationJob().shortAnswer() != null) { shortAnswer = parseShortAnswerString(testGenerationResponse.testGenerationJob().shortAnswer()) if (shortAnswer.stopIteration == "true") { - throw Exception("${shortAnswer.planSummary}") - throw codeTestServerException("TestGenFailedError: ${shortAnswer.planSummary}", "400", "TestGenFailedError", shortAnswer.planSummary) + codeTestServerException("TestGenFailedError: ${shortAnswer.planSummary}", 400, "TestGenFailedError", shortAnswer.planSummary) } } // If job status is Failed and has no ShortAnswer then there might be some issue in the backend. - throw codeTestServerException( + codeTestServerException( "TestGenFailedError: " + message("testgen.message.failed"), - "500", + 500, "TestGenFailedError", message("testgen.error.generic_technical_error_message") ) @@ -229,7 +231,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin if (previousIterationContext == null && testGenerationResponse.testGenerationJob().shortAnswer() != null) { shortAnswer = parseShortAnswerString(testGenerationResponse.testGenerationJob().shortAnswer()) if (shortAnswer.stopIteration == "true") { - throw codeTestServerException("TestGenFailedError: ${shortAnswer.planSummary}", "400", "TestGenFailedError", shortAnswer.planSummary) + codeTestServerException("TestGenFailedError: ${shortAnswer.planSummary}", 400, "TestGenFailedError", shortAnswer.planSummary) } codeTestChatHelper.updateAnswer( CodeTestChatMessageContent( @@ -261,9 +263,9 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin }, { e -> LOG.error(e) { "ExportResultArchive failed: ${e.message}" } - throw codeTestServerException( + codeTestServerException( "ExportResultsArchiveError: ${e.message}", - "500", + 500, "ExportResultsArchiveError", message("testgen.error.generic_technical_error_message") ) @@ -529,7 +531,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin } catch (e: Exception) { // Add an answer for displaying error message val errorMessage = when { - e is CodeTestException && e.statusCode == "400" && + e is CodeTestException && e.statusCode == 400 && e.message?.startsWith("CreateTestJobError: Maximum") == true -> message("testgen.error.maximum_generations_reach") @@ -556,7 +558,7 @@ class CodeWhispererUTGChatManager(val project: Project, private val cs: Coroutin result = if (e.message == message("testgen.message.cancelled")) MetricResult.Cancelled else MetricResult.Failed, reason = (e as CodeTestException).code ?: "DefaultError", reasonDesc = if (e.message == message("testgen.message.cancelled")) "${e.code}: ${e.message}" else e.message, - httpStatusCode = e.statusCode ?: "400", + httpStatusCode = e.statusCode.toString(), perfClientLatency = (Instant.now().toEpochMilli() - session.startTimeOfTestGeneration), isCodeBlockSelected = session.isCodeBlockSelected, artifactsUploadDuration = session.artifactUploadDuration, diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt index d478407d691..4357522a77c 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt @@ -605,7 +605,8 @@ class CodeTestChatController( artifactsUploadDuration = session.artifactUploadDuration, buildPayloadBytes = session.srcPayloadSize, buildZipFileBytes = session.srcZipFileSize, - requestId = session.startTestGenerationRequestId + requestId = session.startTestGenerationRequestId, + httpStatusCode = "200" ) codeTestChatHelper.addAnswer( CodeTestChatMessageContent( @@ -799,7 +800,8 @@ class CodeTestChatController( artifactsUploadDuration = session.artifactUploadDuration, buildPayloadBytes = session.srcPayloadSize, buildZipFileBytes = session.srcZipFileSize, - requestId = session.startTestGenerationRequestId + requestId = session.startTestGenerationRequestId, + httpStatusCode = "200" ) sessionCleanUp(message.tabId) } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt index 1fd2e756aa7..d129a25d990 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/CodeTestException.kt @@ -7,7 +7,7 @@ import software.aws.toolkits.resources.message open class CodeTestException( override val message: String?, - val statusCode: String? = "400", + val statusCode: Int = 400, val code: String? = "DefaultError", val uiMessage: String? = message( "testgen.error.generic_error_message" @@ -15,26 +15,26 @@ open class CodeTestException( ) : RuntimeException() internal fun noFileOpenError(): Nothing = - throw CodeTestException(message("codewhisperer.codescan.no_file_open"), "400", "ProjectZipError") + throw CodeTestException(message("codewhisperer.codescan.no_file_open"), 400, "ProjectZipError") internal fun fileTooLarge(): Nothing = - throw CodeTestException(message("codewhisperer.codescan.file_too_large_telemetry"), "400", "ProjectZipError") + throw CodeTestException(message("codewhisperer.codescan.file_too_large_telemetry"), 400, "ProjectZipError") internal fun cannotFindFile(errorMessage: String, filepath: String): Nothing = error(message("codewhisperer.codescan.file_not_found", filepath, errorMessage)) internal fun cannotFindValidFile(errorMessage: String): Nothing = - throw CodeTestException(errorMessage, "400", "ProjectZipError") + throw CodeTestException(errorMessage, 400, "ProjectZipError") internal fun cannotFindBuildArtifacts(errorMessage: String): Nothing = - throw CodeTestException(errorMessage, "400", "ProjectZipError") + throw CodeTestException(errorMessage, 400, "ProjectZipError") internal fun invalidSourceZipError(): Nothing = - throw CodeTestException(message("codewhisperer.codescan.invalid_source_zip_telemetry"), "400", "InvalidSourceZipError") + throw CodeTestException(message("codewhisperer.codescan.invalid_source_zip_telemetry"), 400, "InvalidSourceZipError") fun codeTestServerException( errorMessage: String, - statusCode: String?, + statusCode: Int, code: String? = "DefaultError", uiMessage: String? = message( "testgen.error.generic_technical_error_message" @@ -43,4 +43,4 @@ fun codeTestServerException( throw CodeTestException(errorMessage, statusCode, code, uiMessage) fun testGenStoppedError(): Nothing = - throw CodeTestException(message("testgen.message.cancelled"), "400", "TestGenCancelled", message("testgen.message.cancelled")) + throw CodeTestException(message("testgen.message.cancelled"), 400, "TestGenCancelled", message("testgen.message.cancelled")) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt index 542abae566b..e059bcdb0f8 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt @@ -95,7 +95,7 @@ class CodeTestSessionConfig( else -> e.message } LOG.debug { "Error creating payload metadata: $errorMessage" } - throw cannotFindBuildArtifacts(errorMessage ?: message("testgen.message.failed")) + cannotFindBuildArtifacts(errorMessage ?: message("testgen.message.failed")) } // Copy all the included source files to the source zip @@ -219,7 +219,7 @@ class CodeTestSessionConfig( if (maxCountLanguage == null) { programmingLanguage = CodeWhispererUnknownLanguage.INSTANCE - throw cannotFindValidFile("Amazon Q: doesn't contain valid files to generate tests") + cannotFindValidFile("Amazon Q: doesn't contain valid files to generate tests") } programmingLanguage = maxCountLanguage return PayloadMetadata(files, currentTotalFileSize, currentTotalLines, maxCountLanguage.toTelemetryType()) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererZipUploadManager.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererZipUploadManager.kt index 04d9bed768e..4e1799e337a 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererZipUploadManager.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererZipUploadManager.kt @@ -107,10 +107,10 @@ class CodeWhispererZipUploadManager(private val project: Project) { LOG.debug { "$featureUseCase: Artifact failed to upload in the S3 bucket: ${e.message}" } val errorMessage = getTelemetryErrorMessage(e, featureUseCase) when (featureUseCase) { - CodeWhispererConstants.FeatureName.CODE_REVIEW -> throw codeScanServerException("CreateUploadUrlException: $errorMessage") - CodeWhispererConstants.FeatureName.TEST_GENERATION -> throw codeTestServerException( + CodeWhispererConstants.FeatureName.CODE_REVIEW -> codeScanServerException("CreateUploadUrlException: $errorMessage") + CodeWhispererConstants.FeatureName.TEST_GENERATION -> codeTestServerException( "UploadTestArtifactToS3Error: $errorMessage", - "403", + 403, "UploadTestArtifactToS3Error", message("testgen.error.generic_technical_error_message") ) @@ -145,10 +145,10 @@ class CodeWhispererZipUploadManager(private val project: Project) { LOG.debug { "$featureUseCase: Create Upload URL failed: ${e.message}" } val errorMessage = getTelemetryErrorMessage(e, featureUseCase) when (featureUseCase) { - CodeWhispererConstants.FeatureName.CODE_REVIEW -> throw codeScanServerException("CreateUploadUrlException: $errorMessage") - CodeWhispererConstants.FeatureName.TEST_GENERATION -> throw codeTestServerException( + CodeWhispererConstants.FeatureName.CODE_REVIEW -> codeScanServerException("CreateUploadUrlException: $errorMessage") + CodeWhispererConstants.FeatureName.TEST_GENERATION -> codeTestServerException( "CreateUploadUrlError: $errorMessage", - "500", + 500, "CreateUploadUrlError", message("testgen.error.generic_technical_error_message") ) From 0bab6b64a2873ac5cb9b589810b321605e336374 Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Fri, 13 Dec 2024 16:00:38 -0800 Subject: [PATCH 11/15] Adding perfClientLatency to telemetry event (#4) --- .../amazonqCodeTest/controller/CodeTestChatController.kt | 7 +++---- .../jetbrains/services/amazonqCodeTest/session/Session.kt | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt index 4357522a77c..ab0c7f4739a 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt @@ -443,7 +443,6 @@ class CodeTestChatController( var charDifference = 0 var generatedFileContent = "" var selectedFileContent = "" - var latencyOfTestGeneration = 0.0 when (message.actionID) { "utg_view_diff" -> { @@ -487,7 +486,7 @@ class CodeTestChatController( session.linesOfCodeGenerated = lineDifference.coerceAtLeast(0) session.charsOfCodeGenerated = charDifference.coerceAtLeast(0) - latencyOfTestGeneration = (Instant.now().toEpochMilli() - session.startTimeOfTestGeneration) + session.latencyOfTestGeneration = (Instant.now().toEpochMilli() - session.startTimeOfTestGeneration) UiTelemetry.click(null as Project?, "unitTestGeneration_viewDiff") val buttonList = mutableListOf