diff --git a/.changes/next-release/bugfix-554078f3-042e-4b73-8ac4-96085bfc0b8b.json b/.changes/next-release/bugfix-554078f3-042e-4b73-8ac4-96085bfc0b8b.json new file mode 100644 index 00000000000..738a99fd758 --- /dev/null +++ b/.changes/next-release/bugfix-554078f3-042e-4b73-8ac4-96085bfc0b8b.json @@ -0,0 +1,4 @@ +{ + "type" : "bugfix", + "description" : "Amazon Q Feature Dev: display limit reached error message" +} \ No newline at end of file diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt index 57f0dac8ef9..123105e850a 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt @@ -65,7 +65,14 @@ class FeatureDevService(val proxyClient: FeatureDevClient, val project: Project) errMssg = e.awsErrorDetails().errorMessage() logger.warn(e) { "Start conversation failed for request: ${e.requestId()}" } - if (e is software.amazon.awssdk.services.codewhispererruntime.model.ServiceQuotaExceededException) { + // BE service will throw ServiceQuota if conversation limit is reached. API Front-end will throw Throttling with this message if conversation limit is reached + if ( + e is software.amazon.awssdk.services.codewhispererruntime.model.ServiceQuotaExceededException || + ( + e is software.amazon.awssdk.services.codewhispererruntime.model.ThrottlingException && + e.message?.contains("reached for this month.") == true + ) + ) { throw MonthlyConversationLimitError(errMssg, operation = FeatureDevOperation.CreateConversation.toString(), desc = null, cause = e.cause) } } @@ -134,10 +141,19 @@ class FeatureDevService(val proxyClient: FeatureDevClient, val project: Project) errMssg = e.awsErrorDetails().errorMessage() logger.warn(e) { "StartTaskAssistCodeGeneration failed for request: ${e.requestId()}" } - if (e is software.amazon.awssdk.services.codewhispererruntime.model.ServiceQuotaExceededException || ( - e is software.amazon.awssdk.services.codewhispererruntime.model.ThrottlingException && e.message?.contains( - "limit for number of iterations on a code generation" - ) == true + // API Front-end will throw Throttling if conversation limit is reached. API Front-end monitors StartCodeGeneration for throttling + if (e is software.amazon.awssdk.services.codewhispererruntime.model.ThrottlingException && + e.message?.contains("StartTaskAssistCodeGeneration reached for this month.") == true + ) { + throw MonthlyConversationLimitError(errMssg, operation = FeatureDevOperation.StartTaskAssistCodeGeneration.toString(), desc = null, e.cause) + } + // BE service will throw ServiceQuota if code generation iteration limit is reached + else if (e is software.amazon.awssdk.services.codewhispererruntime.model.ServiceQuotaExceededException || ( + e is software.amazon.awssdk.services.codewhispererruntime.model.ThrottlingException && ( + e.message?.contains( + "limit for number of iterations on a code generation" + ) == true + ) ) ) { throw CodeIterationLimitException(operation = FeatureDevOperation.StartTaskAssistCodeGeneration.toString(), desc = null, e.cause) diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevServiceTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevServiceTest.kt index e30259bf2b7..1094e26c8b4 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevServiceTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevServiceTest.kt @@ -24,6 +24,7 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ContentLengthE import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ExportParseException import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.FeatureDevException import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.FeatureDevTestBase +import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.MonthlyConversationLimitError import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.clients.FeatureDevClient import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.CodeGenerationStreamResult import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.CodeReferenceGenerated @@ -195,6 +196,37 @@ class FeatureDevServiceTest : FeatureDevTestBase() { ) } + @Test + fun `test startTaskAssistConversation throws ThrottlingException, different case`() { + val exampleCWException = + ThrottlingException + .builder() + .awsErrorDetails( + AwsErrorDetails.builder().errorMessage("StartTaskAssistCodeGeneration reached for this month.").build(), + ).build() + whenever( + featureDevClient.startTaskAssistCodeGeneration( + testConversationId, + testUploadId, + userMessage, + codeGenerationId = codeGenerationId, + currentCodeGenerationId = "EMPTY_CURRENT_CODE_GENERATION_ID", + ), + ).thenThrow(exampleCWException) + + assertThatThrownBy { + featureDevService.startTaskAssistCodeGeneration( + testConversationId, + testUploadId, + userMessage, + codeGenerationId = codeGenerationId, + currentCodeGenerationId = "EMPTY_CURRENT_CODE_GENERATION_ID", + ) + }.isExactlyInstanceOf(MonthlyConversationLimitError::class.java).withFailMessage( + message("amazonqFeatureDev.exception.monthly_limit_error"), + ) + } + @Test fun `test startTaskAssistConversation throws ServiceQuotaExceededException`() { val exampleCWException =