Skip to content
Draft
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package software.aws.toolkits.jetbrains.services.amazonqFeatureDev

import software.aws.toolkits.jetbrains.services.amazonq.RepoSizeError
import software.aws.toolkits.jetbrains.services.telemetry.SafeMessageError
import software.aws.toolkits.resources.message

/**
Expand All @@ -24,51 +25,51 @@ open class FeatureDevException(override val message: String?, val operation: Str
}

class NoChangeRequiredException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.exception.no_change_required_exception"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.exception.no_change_required_exception"), operation, desc, cause), SafeMessageError

class EmptyPatchException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.exception.guardrails"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.exception.guardrails"), operation, desc, cause), SafeMessageError

class ContentLengthException(
override val message: String = message("amazonqFeatureDev.content_length.error_text"),
operation: String,
desc: String?,
cause: Throwable? = null,
) :
RepoSizeError, FeatureDevException(message, operation, desc, cause)
RepoSizeError, FeatureDevException(message, operation, desc, cause), SafeMessageError

class ZipFileCorruptedException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException("The zip file is corrupted", operation, desc, cause)
FeatureDevException("The zip file is corrupted", operation, desc, cause), SafeMessageError

class UploadURLExpired(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.exception.upload_url_expiry"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.exception.upload_url_expiry"), operation, desc, cause), SafeMessageError

class CodeIterationLimitException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.code_generation.iteration_limit.error_text"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.code_generation.iteration_limit.error_text"), operation, desc, cause), SafeMessageError

class MonthlyConversationLimitError(message: String, operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message, operation, desc, cause)

class GuardrailsException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.exception.guardrails"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.exception.guardrails"), operation, desc, cause), SafeMessageError

class PromptRefusalException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.exception.prompt_refusal"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.exception.prompt_refusal"), operation, desc, cause), SafeMessageError

class ThrottlingException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.exception.throttling"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.exception.throttling"), operation, desc, cause), SafeMessageError

class ExportParseException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.exception.export_parsing_error"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.exception.export_parsing_error"), operation, desc, cause), SafeMessageError

class CodeGenerationException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.code_generation.failed_generation"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.code_generation.failed_generation"), operation, desc, cause), SafeMessageError

class UploadCodeException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.exception.upload_code"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.exception.upload_code"), operation, desc, cause), SafeMessageError

class ConversationIdNotFoundException(operation: String, desc: String?, cause: Throwable? = null) :
FeatureDevException(message("amazonqFeatureDev.exception.conversation_not_found"), operation, desc, cause)
FeatureDevException(message("amazonqFeatureDev.exception.conversation_not_found"), operation, desc, cause), SafeMessageError

val denyListedErrors = arrayOf("Deserialization error", "Inaccessible host", "UnknownHost")
fun createUserFacingErrorMessage(message: String?): String? =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class FeatureDevClient(
requestBuilder.userContext(featureDevUserContext)
}

fun sendFeatureDevMetricData(operationName: String, result: String): SendTelemetryEventResponse =
fun sendFeatureDevMetricData(operationName: String, result: String, log: String?): SendTelemetryEventResponse =
bearerClient().sendTelemetryEvent { requestBuilder ->
requestBuilder.telemetryEvent { telemetryEventBuilder ->
telemetryEventBuilder.metricData {
Expand All @@ -100,16 +100,29 @@ class FeatureDevClient(
.timestamp(Instant.now())
.product("FeatureDev")
.dimensions(
listOf(
Dimension.builder()
.name("operationName")
.value(operationName)
.build(),
Dimension.builder()
.name("result")
.value(result)
.build()
)
buildList {
add(
Dimension.builder()
.name("operationName")
.value(operationName)
.build()
)
add(
Dimension.builder()
.name("result")
.value(result)
.build()
)
if (log != null) {
// The log dimension will be emitted only to CloudWatch Logs
add(
Dimension.builder()
.name("log")
.value(log)
.build()
)
}
}
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@
package software.aws.toolkits.jetbrains.services.amazonqFeatureDev.controller

import com.intellij.notification.NotificationAction
import software.aws.toolkits.jetbrains.services.amazonq.RepoSizeLimitError
import software.aws.toolkits.jetbrains.services.amazonq.messages.MessagePublisher
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.CODE_GENERATION_RETRY_LIMIT
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.CodeIterationLimitException
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ContentLengthException
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.EmptyPatchException
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.GuardrailsException
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.MetricDataOperationName
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.MetricDataResult
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.MonthlyConversationLimitError
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.NoChangeRequiredException
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.PromptRefusalException
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ThrottlingException
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.UploadURLExpired
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.FeatureDevMessageType
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.FollowUp
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.FollowUpStatusType
Expand All @@ -31,6 +36,7 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.Sessio
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.CancellationTokenSource
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.InsertAction
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.getFollowUpOptions
import software.aws.toolkits.jetbrains.services.telemetry.getStackTraceForError
import software.aws.toolkits.jetbrains.utils.notifyInfo
import software.aws.toolkits.resources.message

Expand Down Expand Up @@ -70,8 +76,9 @@ suspend fun FeatureDevController.onCodeGeneration(
messenger.sendUpdatePlaceholder(tabId = tabId, newPlaceholder = message("amazonqFeatureDev.placeholder.generating_code"))

session.sendMetricDataTelemetry(
MetricDataOperationName.StartCodeGeneration,
MetricDataResult.Success
operationName = MetricDataOperationName.StartCodeGeneration,
result = MetricDataResult.Success,
log = null
)

session.send(message) // Trigger code generation
Expand Down Expand Up @@ -153,26 +160,28 @@ suspend fun FeatureDevController.onCodeGeneration(
messenger.sendSystemPrompt(tabId = tabId, followUp = getFollowUpOptions(session.sessionState.phase, InsertAction.ALL))
messenger.sendUpdatePlaceholder(tabId = tabId, newPlaceholder = message("amazonqFeatureDev.placeholder.after_code_generation"))
} catch (err: Exception) {
when (err) {
is GuardrailsException, is NoChangeRequiredException, is PromptRefusalException, is ThrottlingException -> {
session.sendMetricDataTelemetry(
MetricDataOperationName.EndCodeGeneration,
MetricDataResult.Error
)
val result: MetricDataResult = when (err) {
is GuardrailsException, is NoChangeRequiredException, is PromptRefusalException, is ThrottlingException,
is ContentLengthException, is MonthlyConversationLimitError, is CodeIterationLimitException,
is RepoSizeLimitError, is UploadURLExpired,
-> {
MetricDataResult.Error
}

is EmptyPatchException -> {
session.sendMetricDataTelemetry(
MetricDataOperationName.EndCodeGeneration,
MetricDataResult.LlmFailure
)
MetricDataResult.LlmFailure
}

else -> {
session.sendMetricDataTelemetry(
MetricDataOperationName.EndCodeGeneration,
MetricDataResult.Fault
)
MetricDataResult.Fault
}
}

session.sendMetricDataTelemetry(
operationName = MetricDataOperationName.EndCodeGeneration,
result = result,
log = "stack trace: " + getStackTraceForError(err)
)
throw err
} finally {
if (session.sessionState.token
Expand All @@ -195,8 +204,9 @@ suspend fun FeatureDevController.onCodeGeneration(
}

session.sendMetricDataTelemetry(
MetricDataOperationName.EndCodeGeneration,
MetricDataResult.Success
operationName = MetricDataOperationName.EndCodeGeneration,
result = MetricDataResult.Success,
log = null
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ class Session(val tabID: String, val project: Project) {
this._codeResultMessageId = null
}

fun sendMetricDataTelemetry(operationName: MetricDataOperationName, result: MetricDataResult) {
featureDevService.sendFeatureDevMetricData(operationName.toString(), result.toString())
fun sendMetricDataTelemetry(operationName: MetricDataOperationName, result: MetricDataResult, log: String?) {
featureDevService.sendFeatureDevMetricData(operationName.toString(), result.toString(), log)
}

suspend fun send(msg: String): Interaction {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,13 @@ class FeatureDevService(val proxyClient: FeatureDevClient, val project: Project)
}
}

fun sendFeatureDevMetricData(operationName: String, result: String) {
fun sendFeatureDevMetricData(operationName: String, result: String, log: String?) {
val sendFeatureDevTelemetryEventResponse: SendTelemetryEventResponse
try {
sendFeatureDevTelemetryEventResponse = proxyClient.sendFeatureDevMetricData(operationName, result)
sendFeatureDevTelemetryEventResponse = proxyClient.sendFeatureDevMetricData(operationName, result, log)
val requestId = sendFeatureDevTelemetryEventResponse.responseMetadata().requestId()
logger.debug {
"$FEATURE_NAME: succesfully sent feature dev metric data: OperationName: $operationName Result: $result RequestId: $requestId"
"$FEATURE_NAME: succesfully sent feature dev metric data: OperationName: $operationName Result: $result Log: $log RequestId: $requestId"
}
} catch (e: Exception) {
logger.warn(e) { "$FEATURE_NAME: failed to send feature dev metric data" }
Expand Down
Loading
Loading