diff --git a/.changes/next-release/bugfix-caf370b9-c943-4ece-a4c0-81bcefa7a4f5.json b/.changes/next-release/bugfix-caf370b9-c943-4ece-a4c0-81bcefa7a4f5.json new file mode 100644 index 00000000000..e09b9b9d4f2 --- /dev/null +++ b/.changes/next-release/bugfix-caf370b9-c943-4ece-a4c0-81bcefa7a4f5.json @@ -0,0 +1,4 @@ +{ + "type" : "bugfix", + "description" : "Amazon Q Feature Dev: Add error messages when the upload URL expires" +} \ No newline at end of file diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/FeatureDevExceptions.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/FeatureDevExceptions.kt index c23c36c5bf2..3cdbcf1c04f 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/FeatureDevExceptions.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/FeatureDevExceptions.kt @@ -16,6 +16,13 @@ class CodeIterationLimitError(override val message: String, override val cause: class MonthlyConversationLimitError(override val message: String, override val cause: Throwable?) : RuntimeException() +class UploadURLExpired( + override val message: String = message( + "amazonqFeatureDev.exception.upload_url_expiry" + ), + override val cause: Throwable? = null, +) : FeatureDevException(message, cause) + internal fun featureDevServiceError(message: String?): Nothing = throw FeatureDevException(message) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevController.kt index 89f90bd2265..f2c37017c45 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevController.kt @@ -36,6 +36,7 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.FeatureDevExce import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.InboundAppMessagesHandler import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ModifySourceFolderErrorReason import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.MonthlyConversationLimitError +import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.UploadURLExpired import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ZipFileError import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.createUserFacingErrorMessage import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.denyListedErrors @@ -444,6 +445,12 @@ class FeatureDevController( messenger.sendMonthlyLimitError(tabId = tabId) messenger.sendChatInputEnabledMessage(tabId, enabled = false) } + is UploadURLExpired -> messenger.sendAnswer( + tabId = tabId, + message = err.message, + messageType = FeatureDevMessageType.Answer, + canBeVoted = true + ) is FeatureDevException -> { messenger.sendError( tabId = tabId, @@ -471,7 +478,6 @@ class FeatureDevController( ), ) } - else -> { var msg = createUserFacingErrorMessage("$FEATURE_NAME request failed: ${err.message ?: err.cause?.message}") val isDenyListedError = denyListedErrors.any { msg?.contains(it) ?: false } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/UploadArtifact.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/UploadArtifact.kt index 0d88929ee33..66177d5a21f 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/UploadArtifact.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/UploadArtifact.kt @@ -14,6 +14,7 @@ import software.aws.toolkits.jetbrains.services.amazonq.CONTENT_SHA256 import software.aws.toolkits.jetbrains.services.amazonq.SERVER_SIDE_ENCRYPTION import software.aws.toolkits.jetbrains.services.amazonq.SERVER_SIDE_ENCRYPTION_AWS_KMS_KEY_ID import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.FEATURE_NAME +import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.UploadURLExpired import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.clients.FeatureDevClient import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.uploadCodeError import java.io.File @@ -36,9 +37,13 @@ fun uploadArtifactToS3(url: String, fileToUpload: File, checksumSha256: String, connection.setFixedLengthStreamingMode(fileToUpload.length()) IoUtils.copy(fileToUpload.inputStream(), connection.outputStream) } - } catch (err: Exception) { + } catch (err: HttpRequests.HttpStatusException) { logger.warn(err) { "$FEATURE_NAME: Failed to upload code to S3" } - uploadCodeError() + + when (err.statusCode) { + 403 -> throw UploadURLExpired() + else -> uploadCodeError() + } } } 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 50418a9c139..b575a7213df 100644 --- a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -72,6 +72,7 @@ amazonqFeatureDev.exception.request_failed=Request failed amazonqFeatureDev.exception.retry_request_failed=Retry request failed amazonqFeatureDev.exception.throttling=I'm sorry, I'm experiencing high demand at the moment and can't generate your code. This attempt won't count toward usage limits. Please try again. amazonqFeatureDev.exception.upload_code=I'm sorry, I couldn't upload your workspace artifacts to Amazon S3 to help you with this task. You might need to allow access to the S3 bucket. For more information, see the [Amazon Q documentation](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/security_iam_manage-access-with-policies.html#data-perimeters) or contact your network or organization administrator. +amazonqFeatureDev.exception.upload_url_expiry=I'm sorry, I wasn't able to generate code. A connection timed out or became unavailable. Please try again or check the following:\n\n- Exclude non-essential files in your workspace's `.gitignore`.\n\n- Check that your network connection is stable. amazonqFeatureDev.follow_instructions_for_authentication=Follow instructions to re-authenticate ... amazonqFeatureDev.follow_up.close_session=No, thanks amazonqFeatureDev.follow_up.incorrect_source_folder=The folder you chose isn't in your open workspace folder. You can add this folder to your workspace, or choose a folder in your open workspace.