From e961765ab6e9c09a5dee7df5893d9041d0b0ddcd Mon Sep 17 00:00:00 2001 From: laileni Date: Mon, 6 May 2024 17:13:02 -0700 Subject: [PATCH 01/17] Adding specific exception metrics and client messages for QCA --- .../CodeWhispererCodeScanException.kt | 11 ++- .../codescan/CodeWhispererCodeScanManager.kt | 34 ++++++++- .../codescan/CodeWhispererCodeScanSession.kt | 71 ++++++++++++------- .../codescan/CodeWhispererCodeFileScanTest.kt | 4 +- .../codescan/CodeWhispererCodeScanTest.kt | 4 +- .../resources/MessagesBundle.properties | 20 ++++-- 6 files changed, 105 insertions(+), 39 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt index d05e534515..af3d94ccd0 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt @@ -25,5 +25,14 @@ internal fun fileFormatNotSupported(format: String): Nothing = internal fun fileTooLarge(presentableSize: String): Nothing = throw CodeWhispererCodeScanException(message("codewhisperer.codescan.file_too_large", presentableSize)) -internal fun uploadArtifactFailedError(): Nothing = +internal fun uploadArtifactToS3FailedError(): Nothing = throw CodeWhispererCodeScanException(message("codewhisperer.codescan.upload_to_s3_failed")) + +internal fun createUploadUrlFailedError(): Nothing = + throw CodeWhispererCodeScanException(message("codewhisperer.codescan.create_upload_url_failure")) + +internal fun invalidSourceZipError(): Nothing = + throw CodeWhispererCodeScanException(message("codewhisperer.codescan.invalid_source_zip")) + +internal fun createCodeScanFailedError(): Nothing = + throw CodeWhispererCodeScanException(message("codewhisperer.codescan.create_codescan_failure")) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt index b22197e5dd..063d3f1b48 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt @@ -290,6 +290,11 @@ class CodeWhispererCodeScanManager(val project: Project) { else -> null } ?: message("codewhisperer.codescan.run_scan_error") + val telemetryErrorMessage = when (errorMessage) { + message("codewhisperer.codescan.service_error") -> message("codewhisperer.codescan.service_error_telemetry") + else -> errorMessage + } + if (!coroutineContext.isActive) { codeScanResultsPanel.setDefaultUI() } else { @@ -298,7 +303,7 @@ class CodeWhispererCodeScanManager(val project: Project) { } } - return errorMessage + return telemetryErrorMessage } fun handleException(coroutineContext: CoroutineContext, e: Exception, scope: CodeWhispererConstants.CodeAnalysisScope): String { @@ -306,7 +311,7 @@ class CodeWhispererCodeScanManager(val project: Project) { is CodeWhispererException -> e.awsErrorDetails().errorMessage() ?: message("codewhisperer.codescan.service_error") is CodeWhispererCodeScanException -> e.message is WaiterTimeoutException, is TimeoutCancellationException -> message("codewhisperer.codescan.scan_timed_out") - is CancellationException -> "Code scan job cancelled by user." + is CancellationException -> message("codewhisperer.codescan.cancelled_by_user_exception") else -> null } ?: message("codewhisperer.codescan.run_scan_error") @@ -337,7 +342,30 @@ class CodeWhispererCodeScanManager(val project: Project) { "stacktrace: ${e.stackTrace.contentDeepToString()}" } } - return errorMessage + + val telemetryErrorMessage = when (e) { + is CodeWhispererException -> e.awsErrorDetails().errorMessage() ?: message("codewhisperer.codescan.service_error") + is CodeWhispererCodeScanException -> { + when (e.message) { + message("codewhisperer.codescan.no_file_open") -> message("codewhisperer.codescan.no_file_open_telemetry") + message("codewhisperer.codescan.invalid_source_zip") -> message("codewhisperer.codescan.invalid_source_zip_telemetry") + message("codewhisperer.codescan.create_upload_url_failure") -> message("codewhisperer.codescan.create_upload_url_failure_telemetry") + message("codewhisperer.codescan.upload_to_s3_failed") -> message("codewhisperer.codescan.upload_to_s3_failed_telemetry") + message("codewhisperer.codescan.service_error") -> message("codewhisperer.codescan.service_error_telemetry") + message("codewhisperer.codescan.create_codescan_failure") -> message("codewhisperer.codescan.create_codescan_failure_telemetry") + else -> if (e.message?.startsWith("Amazon Q: Selected file is larger than") == true) { + message("codewhisperer.codescan.file_too_large_telemetry") + } else { + e.message + } + } + } + is WaiterTimeoutException, is TimeoutCancellationException -> message("codewhisperer.codescan.scan_timed_out") + is CancellationException -> message("codewhisperer.codescan.cancelled_by_user_exception") + else -> null + } ?: message("codewhisperer.codescan.run_scan_error_telemetry") + + return telemetryErrorMessage } /** diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt index d1e3c6855e..b7e0ea8ddb 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt @@ -244,6 +244,10 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { * Creates an upload URL and uplaods the zip file to the presigned URL */ fun createUploadUrlAndUpload(zipFile: File, artifactType: String, codeScanName: String): CreateUploadUrlResponse = try { + // Throw error if zipFile is invalid. + if (zipFile.path == "") { + invalidSourceZipError() + } val fileMd5: String = Base64.getEncoder().encodeToString(DigestUtils.md5(FileInputStream(zipFile))) val createUploadUrlResponse = createUploadUrl(fileMd5, artifactType, codeScanName) val url = createUploadUrlResponse.uploadUrl() @@ -261,17 +265,22 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { createUploadUrlResponse } catch (e: Exception) { LOG.error { "Security scan failed. Something went wrong uploading artifacts: ${e.message}" } - uploadArtifactFailedError() + throw e } - fun createUploadUrl(md5Content: String, artifactType: String, codeScanName: String): CreateUploadUrlResponse = clientAdaptor.createUploadUrl( - CreateUploadUrlRequest.builder() - .contentMd5(md5Content) - .artifactType(artifactType) - .uploadIntent(getUploadIntent(sessionContext.codeAnalysisScope)) - .uploadContext(UploadContext.fromCodeAnalysisUploadContext(CodeAnalysisUploadContext.builder().codeScanName(codeScanName).build())) - .build() - ) + fun createUploadUrl(md5Content: String, artifactType: String, codeScanName: String): CreateUploadUrlResponse = try { + clientAdaptor.createUploadUrl( + CreateUploadUrlRequest.builder() + .contentMd5(md5Content) + .artifactType(artifactType) + .uploadIntent(getUploadIntent(sessionContext.codeAnalysisScope)) + .uploadContext(UploadContext.fromCodeAnalysisUploadContext(CodeAnalysisUploadContext.builder().codeScanName(codeScanName).build())) + .build() + ) + } catch (e: Exception) { + LOG.error { "Security scan failed. Error creating upload URL: ${e.message}" } + createUploadUrlFailedError() + } private fun getUploadIntent(scope: CodeWhispererConstants.CodeAnalysisScope): UploadIntent = when (scope) { CodeWhispererConstants.CodeAnalysisScope.FILE -> UploadIntent.AUTOMATIC_FILE_SECURITY_SCAN @@ -280,25 +289,33 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { @Throws(IOException::class) fun uploadArtifactToS3(url: String, uploadId: String, fileToUpload: File, md5: String, kmsArn: String?, requestHeaders: Map?) { - val uploadIdJson = """{"uploadId":"$uploadId"}""" - HttpRequests.put(url, "application/zip").userAgent(AwsClientManager.getUserAgent()).tuner { - if (requestHeaders.isNullOrEmpty()) { - it.setRequestProperty(CONTENT_MD5, md5) - it.setRequestProperty(CONTENT_TYPE, APPLICATION_ZIP) - it.setRequestProperty(SERVER_SIDE_ENCRYPTION, AWS_KMS) - if (kmsArn?.isNotEmpty() == true) { - it.setRequestProperty(SERVER_SIDE_ENCRYPTION_AWS_KMS_KEY_ID, kmsArn) - } - it.setRequestProperty(SERVER_SIDE_ENCRYPTION_CONTEXT, Base64.getEncoder().encodeToString(uploadIdJson.toByteArray())) - } else { - requestHeaders.forEach { entry -> - it.setRequestProperty(entry.key, entry.value) + try { + val uploadIdJson = """{"uploadId":"$uploadId"}""" + HttpRequests.put(url, "application/zip").userAgent(AwsClientManager.getUserAgent()).tuner { + if (requestHeaders.isNullOrEmpty()) { + it.setRequestProperty(CONTENT_MD5, md5) + it.setRequestProperty(CONTENT_TYPE, APPLICATION_ZIP) + it.setRequestProperty(SERVER_SIDE_ENCRYPTION, AWS_KMS) + if (kmsArn?.isNotEmpty() == true) { + it.setRequestProperty(SERVER_SIDE_ENCRYPTION_AWS_KMS_KEY_ID, kmsArn) + } + it.setRequestProperty(SERVER_SIDE_ENCRYPTION_CONTEXT, Base64.getEncoder().encodeToString(uploadIdJson.toByteArray())) + } else { + requestHeaders.forEach { entry -> + it.setRequestProperty(entry.key, entry.value) + } } + }.connect { + val connection = it.connection as HttpURLConnection + connection.setFixedLengthStreamingMode(fileToUpload.length()) + IoUtils.copy(fileToUpload.inputStream(), connection.outputStream) } - }.connect { - val connection = it.connection as HttpURLConnection - connection.setFixedLengthStreamingMode(fileToUpload.length()) - IoUtils.copy(fileToUpload.inputStream(), connection.outputStream) + } catch (e: IOException) { + LOG.error { "Security scan failed. Error uploading artifact to S3: ${e.message}" } + throw e + } catch (e: Exception) { + LOG.error { "Security scan failed. Error uploading artifact to S3: ${e.message}" } + uploadArtifactToS3FailedError() } } @@ -320,7 +337,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { ) } catch (e: Exception) { LOG.debug { "Creating security scan failed: ${e.message}" } - throw e + createCodeScanFailedError() } } diff --git a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt index 2a9f7c64b6..17cbf6d665 100644 --- a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt +++ b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt @@ -223,14 +223,14 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn @Test fun `test run() - createCodeScan error`() { mockClient.stub { - onGeneric { createCodeScan(any(), any()) }.thenThrow(CodeWhispererException::class.java) + onGeneric { createCodeScan(any(), any()) }.thenThrow(CodeWhispererCodeScanException::class.java) } runBlocking { val codeScanResponse = codeScanSessionSpy.run() assertThat(codeScanResponse).isInstanceOf() assertThat(codeScanResponse.responseContext.payloadContext).isEqualTo(payloadContext) - assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() + assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() } } diff --git a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt index ca19a9b301..beb5b407a3 100644 --- a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt +++ b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt @@ -212,14 +212,14 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh @Test fun `test run() - createCodeScan error`() { mockClient.stub { - onGeneric { createCodeScan(any(), any()) }.thenThrow(CodeWhispererException::class.java) + onGeneric { createCodeScan(any(), any()) }.thenThrow(CodeWhispererCodeScanException::class.java) } runBlocking { val codeScanResponse = codeScanSessionSpy.run() assertThat(codeScanResponse).isInstanceOf() assertThat(codeScanResponse.responseContext.payloadContext).isEqualTo(payloadContext) - assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() + assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() } } diff --git a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index c343305ecb..38331dd36d 100644 --- a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -703,23 +703,33 @@ codewhisperer.actions.view_documentation.title=View Documentation codewhisperer.codescan.apply_fix_button_label=Apply fix codewhisperer.codescan.apply_fix_button_tooltip=Apply suggested fix codewhisperer.codescan.build_artifacts_not_found=Cannot find build artifacts for the project. Try rebuilding the Java project in IDE or specify compilation output path in File | Project Structure... | Project | Compiler output: +codewhisperer.codescan.cancelled_by_user_exception=Code scan job cancelled by user. codewhisperer.codescan.cannot_read_file=Error while reading file {0} +codewhisperer.codescan.create_codescan_failure=Amazon Q: Can't create code scan. +codewhisperer.codescan.create_codescan_failure_telemetry=Failed in Creating a code scan +codewhisperer.codescan.create_upload_url_failure=Amazon Q: Can't create upload url. +codewhisperer.codescan.create_upload_url_failure_telemetry=Failed to create upload url codewhisperer.codescan.cwe_label=Common Weakness Enumeration (CWE) codewhisperer.codescan.detector_library_label=Detector library codewhisperer.codescan.explain_button_label=Amazon Q: Explain codewhisperer.codescan.file_ext_not_supported=File extension {0} is not supported for Amazon Q Security Scan feature. Please try again with a valid file format - java, python, javascript, typescript, csharp, yaml, json, tf, hcl, ruby, go. codewhisperer.codescan.file_name_issues_count= {0} {1} {2, choice, 1#1 issue|2#{2,number} issues} codewhisperer.codescan.file_not_found=Cannot find file {0} -codewhisperer.codescan.file_too_large=Selected file is larger than {0}. Please try again with a different file. +codewhisperer.codescan.file_too_large=Amazon Q: Selected file is larger than {0}. Please try again with a different file. +codewhisperer.codescan.file_too_large_telemetry=Payload size limit reached. codewhisperer.codescan.fix_applied_fail=Apply fix command failed. {0} codewhisperer.codescan.fix_available_label=Code fix available codewhisperer.codescan.fix_button_label=Fix with Q +codewhisperer.codescan.invalid_source_zip=Amazon Q: Can't find valid source zip. +codewhisperer.codescan.invalid_source_zip_telemetry=Failed to create valid source zip. codewhisperer.codescan.java_module_not_found=Java plugin is required for scanning Java files, install Java plugin or perform the code scan in Intellij Idea instead. -codewhisperer.codescan.no_file_open=No file is open in an active editor. Please open a file in the editor to start the Security Scan. +codewhisperer.codescan.no_file_open=Amazon Q: No file is open in an active editor. Please open a file in the editor to start the Security Scan. +codewhisperer.codescan.no_file_open_telemetry=Open a valid file to scan. codewhisperer.codescan.problems_window_not_found=Unable to display Security Scan results as the Problems View tool window cannot be fetched. codewhisperer.codescan.run_scan=Run Project Scan codewhisperer.codescan.run_scan_complete= Security Scan completed for {0, choice, 1#1 file|2#{0,number} files}. {1, choice, 0#No issues|1#1 issue|2#{1,number} issues} found in {2}. {3, choice, 0# |1# File size limit reached.} Last Run {5} codewhisperer.codescan.run_scan_error=We encountered an error while scanning for security issues. Please try again. +codewhisperer.codescan.run_scan_error_telemetry=Security scan failed. codewhisperer.codescan.run_scan_info=Select 'Run' in toolbar to scan this package for security issues. codewhisperer.codescan.scan_display=Amazon Q Security Issues codewhisperer.codescan.scan_display_with_issues=Amazon Q Security Issues {0} @@ -729,7 +739,8 @@ codewhisperer.codescan.scan_recommendation_invalid= {0} {0} files were scanned during the last security scan. -codewhisperer.codescan.service_error=Security Scan failed. Amazon Q error encountered. Please try again. +codewhisperer.codescan.service_error=Amazon Q: Security scan failed. Please try again. +codewhisperer.codescan.service_error_telemetry=Failed code scan service error codewhisperer.codescan.stop_scan=Stop Security Scan codewhisperer.codescan.stop_scan_confirm_button=Stop scan codewhisperer.codescan.stop_scan_confirm_message=Are you sure you want to stop ongoing security scan? This scan will be counted as one complete scan towards your monthly security scan limits. @@ -737,6 +748,7 @@ codewhisperer.codescan.stopping_scan=Stopping Security Scan... codewhisperer.codescan.suggested_fix_description=Why are we recommending this? codewhisperer.codescan.suggested_fix_label=Suggested code fix preview codewhisperer.codescan.upload_to_s3_failed=Amazon Q is unable to upload workspace artifacts to Amazon S3 for security scans. For more information, see the Amazon Q documentation or contact your network or organization administrator.
https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/security_iam_manage-access-with-policies.html +codewhisperer.codescan.upload_to_s3_failed_telemetry=Failed to upload aritfact to S3. codewhisperer.codescan.view_scanned_files=View {0} scanned files codewhisperer.credential.login.dialog.exception.cancel_login=Login cancelled codewhisperer.credential.login.dialog.ok_button=Connect @@ -803,7 +815,7 @@ codewhisperer.notification.custom.simple.button.select_another_customization=Sel codewhisperer.notification.custom.simple.button.select_customization=Select customization codewhisperer.notification.remote.ide_unsupported.message=Please update your IDE backend to a 2023.3 or later version to continue using Amazon Q inline suggestions. codewhisperer.notification.remote.ide_unsupported.title=Amazon Q inline suggestion not supported in this IDE version -codewhisperer.notification.usage_limit.codescan.warn.content=Maximum project scan count reached for this month. +codewhisperer.notification.usage_limit.codescan.warn.content=You have reached maximum project scan count for this month. codewhisperer.notification.usage_limit.codesuggestion.warn.content=You have reached the monthly fair use limit of code recommendations. codewhisperer.popup.button.accept=
 Insert Code 
\u21E5
codewhisperer.popup.button.next=
Next
From d413c317d97c53fd1d46ab6a6d728e4eaecfc57a Mon Sep 17 00:00:00 2001 From: laileni Date: Tue, 7 May 2024 09:18:53 -0700 Subject: [PATCH 02/17] Fixing typos --- .../aws/toolkits/resources/MessagesBundle.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index 38331dd36d..ea07757ab9 100644 --- a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -706,7 +706,7 @@ codewhisperer.codescan.build_artifacts_not_found=Cannot find build artifac codewhisperer.codescan.cancelled_by_user_exception=Code scan job cancelled by user. codewhisperer.codescan.cannot_read_file=Error while reading file {0} codewhisperer.codescan.create_codescan_failure=Amazon Q: Can't create code scan. -codewhisperer.codescan.create_codescan_failure_telemetry=Failed in Creating a code scan +codewhisperer.codescan.create_codescan_failure_telemetry=Failed in Creating a code scan codewhisperer.codescan.create_upload_url_failure=Amazon Q: Can't create upload url. codewhisperer.codescan.create_upload_url_failure_telemetry=Failed to create upload url codewhisperer.codescan.cwe_label=Common Weakness Enumeration (CWE) @@ -748,7 +748,7 @@ codewhisperer.codescan.stopping_scan=Stopping Security Scan... codewhisperer.codescan.suggested_fix_description=Why are we recommending this? codewhisperer.codescan.suggested_fix_label=Suggested code fix preview codewhisperer.codescan.upload_to_s3_failed=Amazon Q is unable to upload workspace artifacts to Amazon S3 for security scans. For more information, see the Amazon Q documentation or contact your network or organization administrator.
https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/security_iam_manage-access-with-policies.html -codewhisperer.codescan.upload_to_s3_failed_telemetry=Failed to upload aritfact to S3. +codewhisperer.codescan.upload_to_s3_failed_telemetry=Failed to upload artifact to S3. codewhisperer.codescan.view_scanned_files=View {0} scanned files codewhisperer.credential.login.dialog.exception.cancel_login=Login cancelled codewhisperer.credential.login.dialog.ok_button=Connect @@ -815,7 +815,7 @@ codewhisperer.notification.custom.simple.button.select_another_customization=Sel codewhisperer.notification.custom.simple.button.select_customization=Select customization codewhisperer.notification.remote.ide_unsupported.message=Please update your IDE backend to a 2023.3 or later version to continue using Amazon Q inline suggestions. codewhisperer.notification.remote.ide_unsupported.title=Amazon Q inline suggestion not supported in this IDE version -codewhisperer.notification.usage_limit.codescan.warn.content=You have reached maximum project scan count for this month. +codewhisperer.notification.usage_limit.codescan.warn.content=You have reached the maximum project scan count for this month. codewhisperer.notification.usage_limit.codesuggestion.warn.content=You have reached the monthly fair use limit of code recommendations. codewhisperer.popup.button.accept=
 Insert Code 
\u21E5
codewhisperer.popup.button.next=
Next
From 957e394cdee8959166c725d8343785d696cb7424 Mon Sep 17 00:00:00 2001 From: laileni Date: Tue, 7 May 2024 18:36:47 -0700 Subject: [PATCH 03/17] Refactoring code --- .../CodeWhispererCodeScanException.kt | 13 ++------ .../codescan/CodeWhispererCodeScanManager.kt | 31 +++++++------------ .../codescan/CodeWhispererCodeScanSession.kt | 6 ++-- .../sessionconfig/CodeScanSessionConfig.kt | 1 + .../resources/MessagesBundle.properties | 14 +++------ 5 files changed, 23 insertions(+), 42 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt index af3d94ccd0..5028f1522d 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt @@ -11,7 +11,7 @@ internal fun noFileOpenError(): Nothing = throw CodeWhispererCodeScanException(message("codewhisperer.codescan.no_file_open")) internal fun codeScanFailed(): Nothing = - throw CodeWhispererCodeScanException(message("codewhisperer.codescan.service_error")) + throw CodeWhispererCodeScanException(message("codewhisperer.codescan.run_scan_error")) internal fun cannotFindFile(file: String?): Nothing = error(message("codewhisperer.codescan.file_not_found", file ?: "")) @@ -25,14 +25,5 @@ internal fun fileFormatNotSupported(format: String): Nothing = internal fun fileTooLarge(presentableSize: String): Nothing = throw CodeWhispererCodeScanException(message("codewhisperer.codescan.file_too_large", presentableSize)) -internal fun uploadArtifactToS3FailedError(): Nothing = - throw CodeWhispererCodeScanException(message("codewhisperer.codescan.upload_to_s3_failed")) - -internal fun createUploadUrlFailedError(): Nothing = - throw CodeWhispererCodeScanException(message("codewhisperer.codescan.create_upload_url_failure")) - internal fun invalidSourceZipError(): Nothing = - throw CodeWhispererCodeScanException(message("codewhisperer.codescan.invalid_source_zip")) - -internal fun createCodeScanFailedError(): Nothing = - throw CodeWhispererCodeScanException(message("codewhisperer.codescan.create_codescan_failure")) + throw CodeWhispererCodeScanException(message("codewhisperer.codescan.invalid_source_zip_telemetry")) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt index d17e740100..1947cda35f 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt @@ -303,11 +303,6 @@ class CodeWhispererCodeScanManager(val project: Project) { else -> null } ?: message("codewhisperer.codescan.run_scan_error") - val telemetryErrorMessage = when (errorMessage) { - message("codewhisperer.codescan.service_error") -> message("codewhisperer.codescan.service_error_telemetry") - else -> errorMessage - } - if (!coroutineContext.isActive) { codeScanResultsPanel.setDefaultUI() } else { @@ -315,14 +310,16 @@ class CodeWhispererCodeScanManager(val project: Project) { codeScanResultsPanel.showError(errorMessage) } } - - return telemetryErrorMessage + return errorMessage // TODO } fun handleException(coroutineContext: CoroutineContext, e: Exception, scope: CodeWhispererConstants.CodeAnalysisScope): String { val errorMessage = when (e) { is CodeWhispererException -> e.awsErrorDetails().errorMessage() ?: message("codewhisperer.codescan.service_error") - is CodeWhispererCodeScanException -> e.message + is CodeWhispererCodeScanException -> when (e.message) { + message("codewhisperer.codescan.invalid_source_zip_telemetry") -> message("codewhisperer.codescan.run_scan_error") + else -> e.message + } is WaiterTimeoutException, is TimeoutCancellationException -> message("codewhisperer.codescan.scan_timed_out") is CancellationException -> message("codewhisperer.codescan.cancelled_by_user_exception") else -> null @@ -358,24 +355,20 @@ class CodeWhispererCodeScanManager(val project: Project) { val telemetryErrorMessage = when (e) { is CodeWhispererException -> e.awsErrorDetails().errorMessage() ?: message("codewhisperer.codescan.service_error") - is CodeWhispererCodeScanException -> { - when (e.message) { - message("codewhisperer.codescan.no_file_open") -> message("codewhisperer.codescan.no_file_open_telemetry") - message("codewhisperer.codescan.invalid_source_zip") -> message("codewhisperer.codescan.invalid_source_zip_telemetry") - message("codewhisperer.codescan.create_upload_url_failure") -> message("codewhisperer.codescan.create_upload_url_failure_telemetry") - message("codewhisperer.codescan.upload_to_s3_failed") -> message("codewhisperer.codescan.upload_to_s3_failed_telemetry") - message("codewhisperer.codescan.service_error") -> message("codewhisperer.codescan.service_error_telemetry") - message("codewhisperer.codescan.create_codescan_failure") -> message("codewhisperer.codescan.create_codescan_failure_telemetry") - else -> if (e.message?.startsWith("Amazon Q: Selected file is larger than") == true) { + is CodeWhispererCodeScanException -> when (e.message) { + message("codewhisperer.codescan.no_file_open") -> message("codewhisperer.codescan.no_file_open_telemetry") + message("codewhisperer.codescan.run_scan_error") -> message("codewhisperer.codescan.create_codescan_failure_telemetry") + else -> e.message?.let { msg -> + if (msg.startsWith("Amazon Q: The selected file is larger than")) { message("codewhisperer.codescan.file_too_large_telemetry") } else { - e.message + msg } } } is WaiterTimeoutException, is TimeoutCancellationException -> message("codewhisperer.codescan.scan_timed_out") is CancellationException -> message("codewhisperer.codescan.cancelled_by_user_exception") - else -> null + else -> e.message } ?: message("codewhisperer.codescan.run_scan_error_telemetry") return telemetryErrorMessage diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt index a7ef528f2b..4a4ee12ea5 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt @@ -286,7 +286,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { ) } catch (e: Exception) { LOG.error { "Security scan failed. Error creating upload URL: ${e.message}" } - createUploadUrlFailedError() + throw e } private fun getUploadIntent(scope: CodeWhispererConstants.CodeAnalysisScope): UploadIntent = when (scope) { @@ -322,7 +322,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { throw e } catch (e: Exception) { LOG.error { "Security scan failed. Error uploading artifact to S3: ${e.message}" } - uploadArtifactToS3FailedError() + throw e } } @@ -344,7 +344,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { ) } catch (e: Exception) { LOG.debug { "Creating security scan failed: ${e.message}" } - createCodeScanFailedError() + throw e } } diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt index 57cbe6504c..876ba74724 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt @@ -73,6 +73,7 @@ class CodeScanSessionConfig( fun createPayload(): Payload { // Fail fast if the selected file size is greater than the payload limit. +// fileTooLarge(getPresentablePayloadLimit()) if (selectedFile.length > getPayloadLimitInBytes()) { fileTooLarge(getPresentablePayloadLimit()) } diff --git a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index ea07757ab9..770d99d18d 100644 --- a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -706,29 +706,26 @@ codewhisperer.codescan.build_artifacts_not_found=Cannot find build artifac codewhisperer.codescan.cancelled_by_user_exception=Code scan job cancelled by user. codewhisperer.codescan.cannot_read_file=Error while reading file {0} codewhisperer.codescan.create_codescan_failure=Amazon Q: Can't create code scan. -codewhisperer.codescan.create_codescan_failure_telemetry=Failed in Creating a code scan -codewhisperer.codescan.create_upload_url_failure=Amazon Q: Can't create upload url. -codewhisperer.codescan.create_upload_url_failure_telemetry=Failed to create upload url +codewhisperer.codescan.create_codescan_failure_telemetry=Failed code scan service error codewhisperer.codescan.cwe_label=Common Weakness Enumeration (CWE) codewhisperer.codescan.detector_library_label=Detector library codewhisperer.codescan.explain_button_label=Amazon Q: Explain codewhisperer.codescan.file_ext_not_supported=File extension {0} is not supported for Amazon Q Security Scan feature. Please try again with a valid file format - java, python, javascript, typescript, csharp, yaml, json, tf, hcl, ruby, go. codewhisperer.codescan.file_name_issues_count= {0} {1} {2, choice, 1#1 issue|2#{2,number} issues} codewhisperer.codescan.file_not_found=Cannot find file {0} -codewhisperer.codescan.file_too_large=Amazon Q: Selected file is larger than {0}. Please try again with a different file. +codewhisperer.codescan.file_too_large=Amazon Q: The selected file is larger than {0}. Try again with a smaller file. codewhisperer.codescan.file_too_large_telemetry=Payload size limit reached. codewhisperer.codescan.fix_applied_fail=Apply fix command failed. {0} codewhisperer.codescan.fix_available_label=Code fix available codewhisperer.codescan.fix_button_label=Fix with Q -codewhisperer.codescan.invalid_source_zip=Amazon Q: Can't find valid source zip. codewhisperer.codescan.invalid_source_zip_telemetry=Failed to create valid source zip. codewhisperer.codescan.java_module_not_found=Java plugin is required for scanning Java files, install Java plugin or perform the code scan in Intellij Idea instead. -codewhisperer.codescan.no_file_open=Amazon Q: No file is open in an active editor. Please open a file in the editor to start the Security Scan. +codewhisperer.codescan.no_file_open=Amazon Q: No file is open in an active editor. Open a file in the editor to start a Security Scan. codewhisperer.codescan.no_file_open_telemetry=Open a valid file to scan. codewhisperer.codescan.problems_window_not_found=Unable to display Security Scan results as the Problems View tool window cannot be fetched. codewhisperer.codescan.run_scan=Run Project Scan codewhisperer.codescan.run_scan_complete= Security Scan completed for {0, choice, 1#1 file|2#{0,number} files}. {1, choice, 0#No issues|1#1 issue|2#{1,number} issues} found in {2}. {3, choice, 0# |1# File size limit reached.} Last Run {5} -codewhisperer.codescan.run_scan_error=We encountered an error while scanning for security issues. Please try again. +codewhisperer.codescan.run_scan_error=Amazon Q encountered an error while scanning for security issues. Try again later. codewhisperer.codescan.run_scan_error_telemetry=Security scan failed. codewhisperer.codescan.run_scan_info=Select 'Run' in toolbar to scan this package for security issues. codewhisperer.codescan.scan_display=Amazon Q Security Issues @@ -747,8 +744,7 @@ codewhisperer.codescan.stop_scan_confirm_message=Are you sure you want to stop o codewhisperer.codescan.stopping_scan=Stopping Security Scan... codewhisperer.codescan.suggested_fix_description=Why are we recommending this? codewhisperer.codescan.suggested_fix_label=Suggested code fix preview -codewhisperer.codescan.upload_to_s3_failed=Amazon Q is unable to upload workspace artifacts to Amazon S3 for security scans. For more information, see the Amazon Q documentation or contact your network or organization administrator.
https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/security_iam_manage-access-with-policies.html -codewhisperer.codescan.upload_to_s3_failed_telemetry=Failed to upload artifact to S3. +codewhisperer.codescan.upload_to_s3_failed_customer_message=Amazon Q is unable to upload workspace artifacts to Amazon S3 for security scans. For more information, see the Amazon Q documentation or contact your network or organization administrator.
https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/security_iam_manage-access-with-policies.html codewhisperer.codescan.view_scanned_files=View {0} scanned files codewhisperer.credential.login.dialog.exception.cancel_login=Login cancelled codewhisperer.credential.login.dialog.ok_button=Connect From 75418862da9843cf97246b529d5e607af43661e5 Mon Sep 17 00:00:00 2001 From: laileni Date: Tue, 7 May 2024 19:01:29 -0700 Subject: [PATCH 04/17] Removing redundant code --- .../codescan/CodeWhispererCodeScanManager.kt | 9 +++++---- .../codescan/sessionconfig/CodeScanSessionConfig.kt | 1 - .../aws/toolkits/resources/MessagesBundle.properties | 4 ---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt index 1947cda35f..f879854458 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt @@ -297,7 +297,7 @@ class CodeWhispererCodeScanManager(val project: Project) { if (e.cause?.message?.contains("com.intellij.openapi.compiler.CompilerPaths") == true) { message("codewhisperer.codescan.java_module_not_found") } else { - message("codewhisperer.codescan.service_error") + null } } else -> null @@ -310,12 +310,13 @@ class CodeWhispererCodeScanManager(val project: Project) { codeScanResultsPanel.showError(errorMessage) } } - return errorMessage // TODO + + return errorMessage } fun handleException(coroutineContext: CoroutineContext, e: Exception, scope: CodeWhispererConstants.CodeAnalysisScope): String { val errorMessage = when (e) { - is CodeWhispererException -> e.awsErrorDetails().errorMessage() ?: message("codewhisperer.codescan.service_error") + is CodeWhispererException -> e.awsErrorDetails().errorMessage() ?: message("codewhisperer.codescan.run_scan_error") is CodeWhispererCodeScanException -> when (e.message) { message("codewhisperer.codescan.invalid_source_zip_telemetry") -> message("codewhisperer.codescan.run_scan_error") else -> e.message @@ -354,7 +355,7 @@ class CodeWhispererCodeScanManager(val project: Project) { } val telemetryErrorMessage = when (e) { - is CodeWhispererException -> e.awsErrorDetails().errorMessage() ?: message("codewhisperer.codescan.service_error") + is CodeWhispererException -> e.awsErrorDetails().errorMessage() ?: message("codewhisperer.codescan.run_scan_error_telemetry") is CodeWhispererCodeScanException -> when (e.message) { message("codewhisperer.codescan.no_file_open") -> message("codewhisperer.codescan.no_file_open_telemetry") message("codewhisperer.codescan.run_scan_error") -> message("codewhisperer.codescan.create_codescan_failure_telemetry") diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt index 876ba74724..57cbe6504c 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt @@ -73,7 +73,6 @@ class CodeScanSessionConfig( fun createPayload(): Payload { // Fail fast if the selected file size is greater than the payload limit. -// fileTooLarge(getPresentablePayloadLimit()) if (selectedFile.length > getPayloadLimitInBytes()) { fileTooLarge(getPresentablePayloadLimit()) } diff --git a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index 770d99d18d..2873d07453 100644 --- a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -705,7 +705,6 @@ codewhisperer.codescan.apply_fix_button_tooltip=Apply suggested fix codewhisperer.codescan.build_artifacts_not_found=Cannot find build artifacts for the project. Try rebuilding the Java project in IDE or specify compilation output path in File | Project Structure... | Project | Compiler output: codewhisperer.codescan.cancelled_by_user_exception=Code scan job cancelled by user. codewhisperer.codescan.cannot_read_file=Error while reading file {0} -codewhisperer.codescan.create_codescan_failure=Amazon Q: Can't create code scan. codewhisperer.codescan.create_codescan_failure_telemetry=Failed code scan service error codewhisperer.codescan.cwe_label=Common Weakness Enumeration (CWE) codewhisperer.codescan.detector_library_label=Detector library @@ -736,15 +735,12 @@ codewhisperer.codescan.scan_recommendation_invalid= {0} {0} files were scanned during the last security scan. -codewhisperer.codescan.service_error=Amazon Q: Security scan failed. Please try again. -codewhisperer.codescan.service_error_telemetry=Failed code scan service error codewhisperer.codescan.stop_scan=Stop Security Scan codewhisperer.codescan.stop_scan_confirm_button=Stop scan codewhisperer.codescan.stop_scan_confirm_message=Are you sure you want to stop ongoing security scan? This scan will be counted as one complete scan towards your monthly security scan limits. codewhisperer.codescan.stopping_scan=Stopping Security Scan... codewhisperer.codescan.suggested_fix_description=Why are we recommending this? codewhisperer.codescan.suggested_fix_label=Suggested code fix preview -codewhisperer.codescan.upload_to_s3_failed_customer_message=Amazon Q is unable to upload workspace artifacts to Amazon S3 for security scans. For more information, see the Amazon Q documentation or contact your network or organization administrator.
https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/security_iam_manage-access-with-policies.html codewhisperer.codescan.view_scanned_files=View {0} scanned files codewhisperer.credential.login.dialog.exception.cancel_login=Login cancelled codewhisperer.credential.login.dialog.ok_button=Connect From ca5b44bab7b02e8291d54e112febc246649fd8f4 Mon Sep 17 00:00:00 2001 From: laileni Date: Tue, 7 May 2024 20:07:10 -0700 Subject: [PATCH 05/17] minor changes --- .../software/aws/toolkits/resources/MessagesBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index e8f222500d..1e3ecb778f 100644 --- a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -807,7 +807,7 @@ codewhisperer.notification.custom.simple.button.select_another_customization=Sel codewhisperer.notification.custom.simple.button.select_customization=Select customization codewhisperer.notification.remote.ide_unsupported.message=Please update your IDE backend to a 2023.3 or later version to continue using Amazon Q inline suggestions. codewhisperer.notification.remote.ide_unsupported.title=Amazon Q inline suggestion not supported in this IDE version -codewhisperer.notification.usage_limit.codescan.warn.content=You have reached the maximum project scan count for this month. +codewhisperer.notification.usage_limit.codescan.warn.content=You have reached the monthly limit for project scans. codewhisperer.notification.usage_limit.codesuggestion.warn.content=You have reached the monthly fair use limit of code recommendations. codewhisperer.popup.button.accept=
 Insert Code 
\u21E5
codewhisperer.popup.button.next=
Next
From 3ef86c06a4c6e72d10c8ab8cbeabf1fdd68a11af Mon Sep 17 00:00:00 2001 From: laileni Date: Wed, 8 May 2024 16:59:09 -0700 Subject: [PATCH 06/17] Addressing comments --- .../codescan/CodeWhispererCodeScanException.kt | 8 ++++---- .../codescan/CodeWhispererCodeScanManager.kt | 11 +++-------- .../codescan/CodeWhispererCodeScanSession.kt | 4 ++-- .../codescan/sessionconfig/CodeScanSessionConfig.kt | 2 +- .../aws/toolkits/resources/MessagesBundle.properties | 11 ++++++----- 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt index 9054c83ff3..3edd975b0e 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt @@ -10,8 +10,8 @@ open class CodeWhispererCodeScanException(override val message: String?) : Runti internal fun noFileOpenError(): Nothing = throw CodeWhispererCodeScanException(message("codewhisperer.codescan.no_file_open")) -internal fun codeScanFailed(): Nothing = - throw CodeWhispererCodeScanException(message("codewhisperer.codescan.run_scan_error")) +internal fun codeScanFailed(errorMessage: String): Nothing = + throw Exception(errorMessage) internal fun cannotFindFile(file: String?): Nothing = error(message("codewhisperer.codescan.file_not_found", file ?: "")) @@ -22,8 +22,8 @@ internal fun cannotFindBuildArtifacts(): Nothing = internal fun fileFormatNotSupported(format: String): Nothing = throw CodeWhispererCodeScanException(message("codewhisperer.codescan.file_ext_not_supported", format)) -internal fun fileTooLarge(presentableSize: String): Nothing = - throw CodeWhispererCodeScanException(message("codewhisperer.codescan.file_too_large", presentableSize)) +internal fun fileTooLarge(): Nothing = + throw CodeWhispererCodeScanException(message("codewhisperer.codescan.file_too_large")) internal fun invalidSourceZipError(): Nothing = throw CodeWhispererCodeScanException(message("codewhisperer.codescan.invalid_source_zip_telemetry")) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt index 6c6ffff78b..3a81fa9279 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt @@ -357,14 +357,9 @@ class CodeWhispererCodeScanManager(val project: Project) { is CodeWhispererException -> e.awsErrorDetails().errorMessage() ?: message("codewhisperer.codescan.run_scan_error_telemetry") is CodeWhispererCodeScanException -> when (e.message) { message("codewhisperer.codescan.no_file_open") -> message("codewhisperer.codescan.no_file_open_telemetry") - message("codewhisperer.codescan.run_scan_error") -> message("codewhisperer.codescan.create_codescan_failure_telemetry") - else -> e.message?.let { msg -> - if (msg.startsWith("Amazon Q: The selected file is larger than")) { - message("codewhisperer.codescan.file_too_large_telemetry") - } else { - msg - } - } + message("codewhisperer.codescan.unsupported_language_error") -> message("codewhisperer.codescan.unsupported_language_error_telemetry") + message("codewhisperer.codescan.file_too_large") -> message("codewhisperer.codescan.file_too_large_telemetry") + else -> e.message } is WaiterTimeoutException, is TimeoutCancellationException -> message("codewhisperer.codescan.scan_timed_out") is CancellationException -> message("codewhisperer.codescan.cancelled_by_user_exception") diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt index 4a4ee12ea5..5ce898c64d 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt @@ -152,7 +152,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { "Status: ${createCodeScanResponse.status()} for request id: ${createCodeScanResponse.responseMetadata().requestId()}" } } - codeScanFailed() + codeScanFailed(createCodeScanResponse.errorMessage()) } val jobId = createCodeScanResponse.jobId() codeScanResponseContext = codeScanResponseContext.copy(codeScanJobId = jobId) @@ -188,7 +188,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { "Status: ${getCodeScanResponse.status()} for request id: ${getCodeScanResponse.responseMetadata().requestId()}" } } - codeScanFailed() + codeScanFailed(getCodeScanResponse.errorMessage()) } } diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt index 0fc6f5c744..44390f97dd 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt @@ -88,7 +88,7 @@ class CodeScanSessionConfig( // Fail fast if the selected file size is greater than the payload limit. if (selectedFile != null && selectedFile.length > getPayloadLimitInBytes()) { - fileTooLarge(getPresentablePayloadLimit()) + fileTooLarge() } val start = Instant.now().toEpochMilli() diff --git a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index 6f11a3b198..1808bbe08b 100644 --- a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -712,19 +712,19 @@ codewhisperer.codescan.explain_button_label=Amazon Q: Explain codewhisperer.codescan.file_ext_not_supported=File extension {0} is not supported for Amazon Q Security Scan feature. Please try again with a valid file format - java, python, javascript, typescript, csharp, yaml, json, tf, hcl, ruby, go. codewhisperer.codescan.file_name_issues_count= {0} {1} {2, choice, 1#1 issue|2#{2,number} issues} codewhisperer.codescan.file_not_found=Cannot find file {0} -codewhisperer.codescan.file_too_large=Amazon Q: The selected file is larger than {0}. Try again with a smaller file. +codewhisperer.codescan.file_too_large=Amazon Q: The selected file exceeds the input artifact limit. Try again with a smaller file. For more information about scan limits, see the Amazon Q documentation. codewhisperer.codescan.file_too_large_telemetry=Payload size limit reached. codewhisperer.codescan.fix_applied_fail=Apply fix command failed. {0} codewhisperer.codescan.fix_available_label=Code fix available codewhisperer.codescan.fix_button_label=Fix with Q codewhisperer.codescan.invalid_source_zip_telemetry=Failed to create valid source zip. codewhisperer.codescan.java_module_not_found=Java plugin is required for scanning Java files, install Java plugin or perform the code scan in Intellij Idea instead. -codewhisperer.codescan.no_file_open=Amazon Q: No file is open in an active editor. Open a file in the editor to start a Security Scan. +codewhisperer.codescan.no_file_open=Amazon Q: No file is open in an active editor. Open a file to start a Security Scan. codewhisperer.codescan.no_file_open_telemetry=Open a valid file to scan. codewhisperer.codescan.problems_window_not_found=Unable to display Security Scan results as the Problems View tool window cannot be fetched. codewhisperer.codescan.run_scan=Run Project Scan codewhisperer.codescan.run_scan_complete= Security Scan completed for {0, choice, 1#1 file|2#{0,number} files}. {1, choice, 0#No issues|1#1 issue|2#{1,number} issues} found in {2}. {3, choice, 0# |1# File size limit reached.} Last Run {5} -codewhisperer.codescan.run_scan_error=Amazon Q encountered an error while scanning for security issues. Try again later. +codewhisperer.codescan.run_scan_error=Amazon Q encountered an error while scanning for security issues. Please try again later. codewhisperer.codescan.run_scan_error_telemetry=Security scan failed. codewhisperer.codescan.run_scan_info=Select 'Run' in toolbar to scan this package for security issues. codewhisperer.codescan.scan_display=Amazon Q Security Issues @@ -741,7 +741,8 @@ codewhisperer.codescan.stop_scan_confirm_message=Are you sure you want to stop o codewhisperer.codescan.stopping_scan=Stopping Security Scan... codewhisperer.codescan.suggested_fix_description=Why are we recommending this? codewhisperer.codescan.suggested_fix_label=Suggested code fix preview -codewhisperer.codescan.unsupported_language_error=Project does not contain valid files to scan +codewhisperer.codescan.unsupported_language_error=Amazon Q: Project does not contain valid files to scan +codewhisperer.codescan.unsupported_language_error_telemetry=Project does not contain valid files to scan codewhisperer.codescan.view_scanned_files=View {0} scanned files codewhisperer.credential.login.dialog.exception.cancel_login=Login cancelled codewhisperer.credential.login.dialog.ok_button=Connect @@ -808,7 +809,7 @@ codewhisperer.notification.custom.simple.button.select_another_customization=Sel codewhisperer.notification.custom.simple.button.select_customization=Select customization codewhisperer.notification.remote.ide_unsupported.message=Please update your IDE backend to a 2023.3 or later version to continue using Amazon Q inline suggestions. codewhisperer.notification.remote.ide_unsupported.title=Amazon Q inline suggestion not supported in this IDE version -codewhisperer.notification.usage_limit.codescan.warn.content=You have reached the monthly limit for project scans. +codewhisperer.notification.usage_limit.codescan.warn.content=Amazon Q: You have reached the monthly limit for project scans. codewhisperer.notification.usage_limit.codesuggestion.warn.content=You have reached the monthly fair use limit of code recommendations. codewhisperer.popup.button.accept=
 Insert Code 
\u21E5
codewhisperer.popup.button.next=
Next
From a971704090667f71540b0164d752cfc272e917ff Mon Sep 17 00:00:00 2001 From: laileni Date: Wed, 8 May 2024 18:03:18 -0700 Subject: [PATCH 07/17] Adding null checks to error messages --- .../codewhisperer/codescan/CodeWhispererCodeScanSession.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt index 5ce898c64d..46bc8307e9 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt @@ -152,7 +152,8 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { "Status: ${createCodeScanResponse.status()} for request id: ${createCodeScanResponse.responseMetadata().requestId()}" } } - codeScanFailed(createCodeScanResponse.errorMessage()) + val errorMessage = createCodeScanResponse.errorMessage()?.let { it } ?: "Security scan failed." + codeScanFailed(errorMessage) } val jobId = createCodeScanResponse.jobId() codeScanResponseContext = codeScanResponseContext.copy(codeScanJobId = jobId) @@ -188,7 +189,8 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { "Status: ${getCodeScanResponse.status()} for request id: ${getCodeScanResponse.responseMetadata().requestId()}" } } - codeScanFailed(getCodeScanResponse.errorMessage()) + val errorMessage = getCodeScanResponse.errorMessage()?.let { it } ?: "Security scan failed." + codeScanFailed(errorMessage) } } From 681e492d931e5b3ccae44e2de3039956ed6936ad Mon Sep 17 00:00:00 2001 From: laileni Date: Wed, 8 May 2024 18:35:37 -0700 Subject: [PATCH 08/17] Adding null checks to error messages --- .../codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt | 4 ++-- .../codewhisperer/codescan/CodeWhispererCodeScanTest.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt index 6fca36e0cf..d0430abbb3 100644 --- a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt +++ b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt @@ -274,7 +274,7 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn val codeScanResponse = codeScanSessionSpy.run() assertThat(codeScanResponse).isInstanceOf() assertThat(codeScanResponse.responseContext.payloadContext).isEqualTo(payloadContext) - assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() + assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() } } @@ -302,7 +302,7 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn val codeScanResponse = codeScanSessionSpy.run() assertThat(codeScanResponse).isInstanceOf() assertThat(codeScanResponse.responseContext.payloadContext).isEqualTo(payloadContext) - assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() + assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() } } diff --git a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt index d5a01318dc..75656ea66a 100644 --- a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt +++ b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt @@ -205,7 +205,7 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh val codeScanResponse = codeScanSessionSpy.run() assertThat(codeScanResponse).isInstanceOf() assertThat(codeScanResponse.responseContext.payloadContext).isEqualTo(payloadContext) - assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() + assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() } } @@ -233,7 +233,7 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh val codeScanResponse = codeScanSessionSpy.run() assertThat(codeScanResponse).isInstanceOf() assertThat(codeScanResponse.responseContext.payloadContext).isEqualTo(payloadContext) - assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() + assertThat((codeScanResponse as CodeScanResponse.Failure).failureReason).isInstanceOf() } } From bd6b0088921159ca9138fa6f8b34c26686971167 Mon Sep 17 00:00:00 2001 From: laileni Date: Wed, 8 May 2024 19:49:01 -0700 Subject: [PATCH 09/17] Removed redundant code in messagesBundle.props --- .../software/aws/toolkits/resources/MessagesBundle.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index 1808bbe08b..f6980d974c 100644 --- a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -705,7 +705,6 @@ codewhisperer.codescan.apply_fix_button_tooltip=Apply suggested fix codewhisperer.codescan.build_artifacts_not_found=Cannot find build artifacts for the project. Try rebuilding the Java project in IDE or specify compilation output path in File | Project Structure... | Project | Compiler output: codewhisperer.codescan.cancelled_by_user_exception=Code scan job cancelled by user. codewhisperer.codescan.cannot_read_file=Error while reading file {0} -codewhisperer.codescan.create_codescan_failure_telemetry=Failed code scan service error codewhisperer.codescan.cwe_label=Common Weakness Enumeration (CWE) codewhisperer.codescan.detector_library_label=Detector library codewhisperer.codescan.explain_button_label=Amazon Q: Explain From 8c228a9a878a21160d6515f19911dc75ae7b19cb Mon Sep 17 00:00:00 2001 From: laileni Date: Wed, 8 May 2024 20:58:08 -0700 Subject: [PATCH 10/17] Removed redundant functions --- .../CodeWhispererCodeScanIntegrationTest.kt | 9 +-------- .../codescan/sessionconfig/CodeScanSessionConfig.kt | 7 ------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/it/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeScanIntegrationTest.kt b/plugins/toolkit/jetbrains-core/it/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeScanIntegrationTest.kt index 07e3ca6c2c..51a08e9a5d 100644 --- a/plugins/toolkit/jetbrains-core/it/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeScanIntegrationTest.kt +++ b/plugins/toolkit/jetbrains-core/it/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeScanIntegrationTest.kt @@ -8,8 +8,6 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Test import software.aws.toolkits.jetbrains.services.codewhisperer.CodeWhispererTestUtil.cppFileName import software.aws.toolkits.jetbrains.services.codewhisperer.CodeWhispererTestUtil.cppTestLeftContext -import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.sessionconfig.CodeScanSessionConfig -import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants import software.aws.toolkits.jetbrains.utils.rules.RunWithRealCredentials.RequiresRealCredentials import software.aws.toolkits.resources.message @@ -59,12 +57,7 @@ class CodeWhispererCodeScanIntegrationTest : CodeWhispererIntegrationTestBase() } testCodeScanWithErrorMessage( message( - "codewhisperer.codescan.file_too_large", - CodeScanSessionConfig.create( - file.virtualFile, - projectRule.project, - CodeWhispererConstants.CodeAnalysisScope.PROJECT - ).getPresentablePayloadLimit() + "codewhisperer.codescan.file_too_large" ) ) } diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt index 44390f97dd..015c5013a9 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/sessionconfig/CodeScanSessionConfig.kt @@ -30,8 +30,6 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhisperer import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.DEFAULT_PAYLOAD_LIMIT_IN_BYTES import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.FILE_SCAN_PAYLOAD_SIZE_LIMIT_IN_BYTES import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.FILE_SCAN_TIMEOUT_IN_SECONDS -import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.TOTAL_BYTES_IN_KB -import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.TOTAL_BYTES_IN_MB import software.aws.toolkits.telemetry.CodewhispererLanguage import java.io.File import java.nio.file.Files @@ -132,11 +130,6 @@ class CodeScanSessionConfig( */ fun createPayloadTimeoutInSeconds(): Long = CODE_SCAN_CREATE_PAYLOAD_TIMEOUT_IN_SECONDS - fun getPresentablePayloadLimit(): String = when (getPayloadLimitInBytes() >= TOTAL_BYTES_IN_MB) { - true -> "${getPayloadLimitInBytes() / TOTAL_BYTES_IN_MB}MB" - false -> "${getPayloadLimitInBytes() / TOTAL_BYTES_IN_KB}KB" - } - private fun countLinesInVirtualFile(virtualFile: VirtualFile): Int { val bufferedReader = virtualFile.inputStream.bufferedReader() return bufferedReader.useLines { lines -> lines.count() } From 2b3ea126d7244bf52d4790ea1688e6af76280e59 Mon Sep 17 00:00:00 2001 From: laileni Date: Thu, 9 May 2024 10:24:33 -0700 Subject: [PATCH 11/17] Removing the LOG.error messages from codescans --- .../codewhisperer/codescan/CodeWhispererCodeScanSession.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt index 46bc8307e9..da85933ae1 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt @@ -273,7 +273,6 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { ) createUploadUrlResponse } catch (e: Exception) { - LOG.error { "Security scan failed. Something went wrong uploading artifacts: ${e.message}" } throw e } @@ -287,7 +286,6 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { .build() ) } catch (e: Exception) { - LOG.error { "Security scan failed. Error creating upload URL: ${e.message}" } throw e } @@ -320,10 +318,8 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { IoUtils.copy(fileToUpload.inputStream(), connection.outputStream) } } catch (e: IOException) { - LOG.error { "Security scan failed. Error uploading artifact to S3: ${e.message}" } throw e } catch (e: Exception) { - LOG.error { "Security scan failed. Error uploading artifact to S3: ${e.message}" } throw e } } From ebec8b77f10d141f653473007cea21d0f7410b34 Mon Sep 17 00:00:00 2001 From: laileni Date: Thu, 9 May 2024 10:37:43 -0700 Subject: [PATCH 12/17] Added Change log --- .../bugfix-dbdc4495-49ce-4635-939b-9e6f50c105eb.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .changes/next-release/bugfix-dbdc4495-49ce-4635-939b-9e6f50c105eb.json diff --git a/.changes/next-release/bugfix-dbdc4495-49ce-4635-939b-9e6f50c105eb.json b/.changes/next-release/bugfix-dbdc4495-49ce-4635-939b-9e6f50c105eb.json new file mode 100644 index 0000000000..8ba733c87d --- /dev/null +++ b/.changes/next-release/bugfix-dbdc4495-49ce-4635-939b-9e6f50c105eb.json @@ -0,0 +1,4 @@ +{ + "type" : "bugfix", + "description" : "Amazon Q: Added telemetry metrics and modified customer facing messages for Q codescans." +} \ No newline at end of file From 6ef786cd2d834427b0007736ebcc233b66228906 Mon Sep 17 00:00:00 2001 From: laileni Date: Thu, 9 May 2024 11:28:38 -0700 Subject: [PATCH 13/17] Updated Change log --- .../bugfix-dbdc4495-49ce-4635-939b-9e6f50c105eb.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/next-release/bugfix-dbdc4495-49ce-4635-939b-9e6f50c105eb.json b/.changes/next-release/bugfix-dbdc4495-49ce-4635-939b-9e6f50c105eb.json index 8ba733c87d..cb04be7fdd 100644 --- a/.changes/next-release/bugfix-dbdc4495-49ce-4635-939b-9e6f50c105eb.json +++ b/.changes/next-release/bugfix-dbdc4495-49ce-4635-939b-9e6f50c105eb.json @@ -1,4 +1,4 @@ { "type" : "bugfix", - "description" : "Amazon Q: Added telemetry metrics and modified customer facing messages for Q codescans." + "description" : "Security Scan: Improved error notifications" } \ No newline at end of file From f2d07e33ba3bfc6993a40531d7792df46ff1311e Mon Sep 17 00:00:00 2001 From: laileni Date: Thu, 9 May 2024 15:37:23 -0700 Subject: [PATCH 14/17] Adding UploadArtifactToS3 error message to CX --- .../codescan/CodeWhispererCodeScanException.kt | 5 +++++ .../codescan/CodeWhispererCodeScanManager.kt | 2 ++ .../codescan/CodeWhispererCodeScanSession.kt | 8 +++++--- .../aws/toolkits/resources/MessagesBundle.properties | 1 + 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt index 3edd975b0e..d2a7c21a4d 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanException.kt @@ -7,6 +7,8 @@ import software.aws.toolkits.resources.message open class CodeWhispererCodeScanException(override val message: String?) : RuntimeException() +open class UploadCodeScanException(override val message: String?) : Exception() + internal fun noFileOpenError(): Nothing = throw CodeWhispererCodeScanException(message("codewhisperer.codescan.no_file_open")) @@ -25,6 +27,9 @@ internal fun fileFormatNotSupported(format: String): Nothing = internal fun fileTooLarge(): Nothing = throw CodeWhispererCodeScanException(message("codewhisperer.codescan.file_too_large")) +internal fun uploadArtifactFailedError(errorMessage: String): Nothing = + throw UploadCodeScanException(errorMessage) + internal fun invalidSourceZipError(): Nothing = throw CodeWhispererCodeScanException(message("codewhisperer.codescan.invalid_source_zip_telemetry")) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt index 3a81fa9279..5697784919 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanManager.kt @@ -320,6 +320,7 @@ class CodeWhispererCodeScanManager(val project: Project) { message("codewhisperer.codescan.invalid_source_zip_telemetry") -> message("codewhisperer.codescan.run_scan_error") else -> e.message } + is UploadCodeScanException -> message("codewhisperer.codescan.upload_to_s3_failed") is WaiterTimeoutException, is TimeoutCancellationException -> message("codewhisperer.codescan.scan_timed_out") is CancellationException -> message("codewhisperer.codescan.cancelled_by_user_exception") else -> null @@ -361,6 +362,7 @@ class CodeWhispererCodeScanManager(val project: Project) { message("codewhisperer.codescan.file_too_large") -> message("codewhisperer.codescan.file_too_large_telemetry") else -> e.message } + is UploadCodeScanException -> e.message is WaiterTimeoutException, is TimeoutCancellationException -> message("codewhisperer.codescan.scan_timed_out") is CancellationException -> message("codewhisperer.codescan.cancelled_by_user_exception") else -> e.message diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt index da85933ae1..3a56794f8c 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt @@ -57,6 +57,7 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhisperer import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.TOTAL_MILLIS_IN_SECOND import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.notifyErrorCodeWhispererUsageLimit import software.aws.toolkits.jetbrains.utils.assertIsNonDispatchThread +import software.aws.toolkits.resources.message import software.aws.toolkits.telemetry.CodewhispererLanguage import java.io.File import java.io.FileInputStream @@ -152,7 +153,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { "Status: ${createCodeScanResponse.status()} for request id: ${createCodeScanResponse.responseMetadata().requestId()}" } } - val errorMessage = createCodeScanResponse.errorMessage()?.let { it } ?: "Security scan failed." + val errorMessage = createCodeScanResponse.errorMessage()?.let { it } ?: message("codewhisperer.codescan.run_scan_error_telemetry") codeScanFailed(errorMessage) } val jobId = createCodeScanResponse.jobId() @@ -189,7 +190,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { "Status: ${getCodeScanResponse.status()} for request id: ${getCodeScanResponse.responseMetadata().requestId()}" } } - val errorMessage = getCodeScanResponse.errorMessage()?.let { it } ?: "Security scan failed." + val errorMessage = getCodeScanResponse.errorMessage()?.let { it } ?: message("codewhisperer.codescan.run_scan_error_telemetry") codeScanFailed(errorMessage) } } @@ -320,7 +321,8 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { } catch (e: IOException) { throw e } catch (e: Exception) { - throw e + val errorMessage = e.message?.let { it } ?: message("codewhisperer.codescan.run_scan_error_telemetry") + throw uploadArtifactFailedError(errorMessage) } } diff --git a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index f6980d974c..96c8bd8995 100644 --- a/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/toolkit/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -742,6 +742,7 @@ codewhisperer.codescan.suggested_fix_description=Why are we recommending this? codewhisperer.codescan.suggested_fix_label=Suggested code fix preview codewhisperer.codescan.unsupported_language_error=Amazon Q: Project does not contain valid files to scan codewhisperer.codescan.unsupported_language_error_telemetry=Project does not contain valid files to scan +codewhisperer.codescan.upload_to_s3_failed=Amazon Q is unable to upload your workspace artifacts to Amazon S3 for security scans. For more information, see the Amazon Q documentation. codewhisperer.codescan.view_scanned_files=View {0} scanned files codewhisperer.credential.login.dialog.exception.cancel_login=Login cancelled codewhisperer.credential.login.dialog.ok_button=Connect From 8836eb2d0a4d10e700b6112ca9168e1ce8800dda Mon Sep 17 00:00:00 2001 From: laileni Date: Mon, 13 May 2024 17:03:50 -0700 Subject: [PATCH 15/17] Addressing comments --- .../codescan/CodeWhispererCodeScanSession.kt | 8 +++----- .../codescan/CodeWhispererCodeFileScanTest.kt | 10 ++++++++++ .../codescan/CodeWhispererCodeScanTest.kt | 10 ++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt index 3a56794f8c..d530b7fd96 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt @@ -253,9 +253,9 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { /** * Creates an upload URL and uplaods the zip file to the presigned URL */ - fun createUploadUrlAndUpload(zipFile: File, artifactType: String, codeScanName: String): CreateUploadUrlResponse = try { + fun createUploadUrlAndUpload(zipFile: File, artifactType: String, codeScanName: String): CreateUploadUrlResponse { // Throw error if zipFile is invalid. - if (zipFile.path == "") { + if (!zipFile.exists()) { invalidSourceZipError() } val fileMd5: String = Base64.getEncoder().encodeToString(DigestUtils.md5(FileInputStream(zipFile))) @@ -272,9 +272,7 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { createUploadUrlResponse.kmsKeyArn(), createUploadUrlResponse.requestHeaders() ) - createUploadUrlResponse - } catch (e: Exception) { - throw e + return createUploadUrlResponse } fun createUploadUrl(md5Content: String, artifactType: String, codeScanName: String): CreateUploadUrlResponse = try { diff --git a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt index d0430abbb3..97c1e7f166 100644 --- a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt +++ b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt @@ -14,6 +14,7 @@ import org.apache.commons.codec.digest.DigestUtils import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test +import org.junit.jupiter.api.assertThrows import org.mockito.ArgumentMatchers.anyString import org.mockito.Mockito import org.mockito.Mockito.mock @@ -168,6 +169,15 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn ) } + @Test + fun `test createUploadUrlAndUpload() with invalid source zip file`() { + val invalidZipFile = File("/path/file.zip") + + assertThrows { + codeScanSessionSpy.createUploadUrlAndUpload(invalidZipFile, "artifactType", codeScanName) + } + } + @Test fun `test createUploadUrl()`() { val response = codeScanSessionSpy.createUploadUrl("md5", "type", codeScanName) diff --git a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt index 75656ea66a..67968b52e4 100644 --- a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt +++ b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanTest.kt @@ -10,6 +10,7 @@ import org.apache.commons.codec.digest.DigestUtils import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test +import org.junit.jupiter.api.assertThrows import org.mockito.ArgumentMatchers.anyString import org.mockito.internal.verification.Times import org.mockito.kotlin.any @@ -112,6 +113,15 @@ class CodeWhispererCodeScanTest : CodeWhispererCodeScanTestBase(PythonCodeInsigh ) } + @Test + fun `test createUploadUrlAndUpload() with invalid source zip file`() { + val invalidZipFile = File("/path/file.zip") + + assertThrows { + codeScanSessionSpy.createUploadUrlAndUpload(invalidZipFile, "artifactType", codeScanName) + } + } + @Test fun `test createUploadUrl()`() { val response = codeScanSessionSpy.createUploadUrl("md5", "type", codeScanName) From 8a5d1ebe09c4753cd1449bce9a8106a38fca79ed Mon Sep 17 00:00:00 2001 From: laileni Date: Tue, 14 May 2024 16:49:38 -0700 Subject: [PATCH 16/17] Addressing comments --- .../codescan/CodeWhispererCodeScanSession.kt | 2 -- .../codescan/CodeWhispererCodeFileScanTest.kt | 10 ---------- 2 files changed, 12 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt index d530b7fd96..180bf3f6ea 100644 --- a/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt +++ b/plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeScanSession.kt @@ -316,8 +316,6 @@ class CodeWhispererCodeScanSession(val sessionContext: CodeScanSessionContext) { connection.setFixedLengthStreamingMode(fileToUpload.length()) IoUtils.copy(fileToUpload.inputStream(), connection.outputStream) } - } catch (e: IOException) { - throw e } catch (e: Exception) { val errorMessage = e.message?.let { it } ?: message("codewhisperer.codescan.run_scan_error_telemetry") throw uploadArtifactFailedError(errorMessage) diff --git a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt index 97c1e7f166..d0430abbb3 100644 --- a/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt +++ b/plugins/toolkit/jetbrains-core/tst/software/aws/toolkits/jetbrains/services/codewhisperer/codescan/CodeWhispererCodeFileScanTest.kt @@ -14,7 +14,6 @@ import org.apache.commons.codec.digest.DigestUtils import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test -import org.junit.jupiter.api.assertThrows import org.mockito.ArgumentMatchers.anyString import org.mockito.Mockito import org.mockito.Mockito.mock @@ -169,15 +168,6 @@ class CodeWhispererCodeFileScanTest : CodeWhispererCodeScanTestBase(PythonCodeIn ) } - @Test - fun `test createUploadUrlAndUpload() with invalid source zip file`() { - val invalidZipFile = File("/path/file.zip") - - assertThrows { - codeScanSessionSpy.createUploadUrlAndUpload(invalidZipFile, "artifactType", codeScanName) - } - } - @Test fun `test createUploadUrl()`() { val response = codeScanSessionSpy.createUploadUrl("md5", "type", codeScanName) From b0c26fa957be2aeae99e0b50603bb5a23a9736be Mon Sep 17 00:00:00 2001 From: laileni Date: Wed, 15 May 2024 11:19:21 -0700 Subject: [PATCH 17/17] dry run CICD --- .../codewhisperer/CodeWhispererCodeScanIntegrationTest.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/toolkit/jetbrains-core/it/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeScanIntegrationTest.kt b/plugins/toolkit/jetbrains-core/it/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeScanIntegrationTest.kt index 51a08e9a5d..7a0c2f0219 100644 --- a/plugins/toolkit/jetbrains-core/it/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeScanIntegrationTest.kt +++ b/plugins/toolkit/jetbrains-core/it/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeScanIntegrationTest.kt @@ -56,9 +56,7 @@ class CodeWhispererCodeScanIntegrationTest : CodeWhispererIntegrationTestBase() projectRule.fixture.openFileInEditor(file.virtualFile) } testCodeScanWithErrorMessage( - message( - "codewhisperer.codescan.file_too_large" - ) + message("codewhisperer.codescan.file_too_large") ) }