Skip to content

Commit b80479f

Browse files
neilk-awsmanodnyab
andauthored
telemetry(amazonq): Update /dev error classification logic (#5469)
Co-authored-by: manodnyab <66754471+manodnyab@users.noreply.github.com>
1 parent ee12dac commit b80479f

File tree

7 files changed

+135
-70
lines changed

7 files changed

+135
-70
lines changed

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/common/util/AmazonQCodeGenService.kt

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ import software.aws.toolkits.jetbrains.common.session.Intent
2323
import software.aws.toolkits.jetbrains.services.amazonqDoc.docServiceError
2424
import software.aws.toolkits.jetbrains.services.amazonqDoc.session.DocGenerationStreamResult
2525
import software.aws.toolkits.jetbrains.services.amazonqDoc.session.ExportDocTaskAssistResultArchiveStreamResult
26+
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ApiException
2627
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.CodeIterationLimitException
2728
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ContentLengthException
2829
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ExportParseException
2930
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.FEATURE_NAME
3031
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.FeatureDevException
3132
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.FeatureDevOperation
3233
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.MonthlyConversationLimitError
34+
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ServiceException
3335
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ZipFileCorruptedException
3436
import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl
3537
import software.aws.toolkits.resources.message
@@ -70,8 +72,14 @@ class AmazonQCodeGenService(val proxyClient: AmazonQCodeGenerateClient, val proj
7072
if (e is ServiceQuotaExceededException) {
7173
throw MonthlyConversationLimitError(errMssg, operation = FeatureDevOperation.CreateConversation.toString(), desc = null, cause = e.cause)
7274
}
75+
throw ApiException.of(e.statusCode(), errMssg, operation = FeatureDevOperation.CreateConversation.toString(), desc = null, e.cause)
7376
}
74-
throw FeatureDevException(errMssg, operation = FeatureDevOperation.CreateConversation.toString(), desc = null, e.cause)
77+
throw ServiceException(
78+
errMssg ?: "CreateTaskAssistConversation failed",
79+
operation = FeatureDevOperation.CreateConversation.toString(),
80+
desc = null,
81+
e.cause
82+
)
7583
} finally {
7684
AmazonqTelemetry.startConversationInvoke(
7785
amazonqConversationId = conversationId,
@@ -111,8 +119,10 @@ class AmazonQCodeGenService(val proxyClient: AmazonQCodeGenerateClient, val proj
111119
}
112120
throw ContentLengthException(operation = FeatureDevOperation.CreateUploadUrl.toString(), desc = null, cause = e.cause)
113121
}
122+
123+
throw ApiException.of(e.statusCode(), errMssg, operation = FeatureDevOperation.CreateUploadUrl.toString(), desc = null, e.cause)
114124
}
115-
throw FeatureDevException(errMssg, operation = FeatureDevOperation.CreateUploadUrl.toString(), desc = null, e.cause)
125+
throw ServiceException(errMssg ?: "CreateUploadUrl failed", operation = FeatureDevOperation.CreateUploadUrl.toString(), desc = null, e.cause)
116126
}
117127
}
118128

@@ -156,8 +166,14 @@ class AmazonQCodeGenService(val proxyClient: AmazonQCodeGenerateClient, val proj
156166
} else if (e is ValidationException && e.message?.contains("zipped file is corrupted") == true) {
157167
throw ZipFileCorruptedException(operation = FeatureDevOperation.StartTaskAssistCodeGeneration.toString(), desc = null, e.cause)
158168
}
169+
throw ApiException.of(e.statusCode(), errMssg, operation = FeatureDevOperation.StartTaskAssistCodeGeneration.toString(), desc = null, e.cause)
159170
}
160-
throw FeatureDevException(errMssg, operation = FeatureDevOperation.StartTaskAssistCodeGeneration.toString(), desc = null, e.cause)
171+
throw ServiceException(
172+
errMssg ?: "StartTaskAssistCodeGeneration failed",
173+
operation = FeatureDevOperation.StartTaskAssistCodeGeneration.toString(),
174+
desc = null,
175+
e.cause
176+
)
161177
}
162178
}
163179

@@ -180,8 +196,14 @@ class AmazonQCodeGenService(val proxyClient: AmazonQCodeGenerateClient, val proj
180196
if (e is CodeWhispererRuntimeException) {
181197
errMssg = e.awsErrorDetails().errorMessage()
182198
logger.warn(e) { "GetTaskAssistCodeGeneration failed for request: ${e.requestId()}" }
199+
throw ApiException.of(e.statusCode(), errMssg, operation = FeatureDevOperation.GetTaskAssistCodeGeneration.toString(), desc = null, e.cause)
183200
}
184-
throw FeatureDevException(errMssg, operation = FeatureDevOperation.GetTaskAssistCodeGeneration.toString(), desc = null, e.cause)
201+
throw ServiceException(
202+
errMssg ?: "GetTaskAssistCodeGeneration failed",
203+
operation = FeatureDevOperation.GetTaskAssistCodeGeneration.toString(),
204+
desc = null,
205+
e.cause
206+
)
185207
}
186208
}
187209

@@ -198,7 +220,12 @@ class AmazonQCodeGenService(val proxyClient: AmazonQCodeGenerateClient, val proj
198220
errMssg = e.awsErrorDetails().errorMessage()
199221
logger.warn(e) { "ExportTaskAssistArchiveResult failed for request: ${e.requestId()}" }
200222
}
201-
throw FeatureDevException(errMssg, operation = FeatureDevOperation.ExportTaskAssistArchiveResult.toString(), desc = null, e.cause)
223+
throw ServiceException(
224+
errMssg ?: "ExportTaskAssistArchive failed",
225+
operation = FeatureDevOperation.ExportTaskAssistArchiveResult.toString(),
226+
desc = null,
227+
e.cause
228+
)
202229
}
203230

204231
val parsedResult: ExportDocTaskAssistResultArchiveStreamResult

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/FeatureDevConstants.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ const val DEFAULT_RETRY_LIMIT = 0
2020
const val MAX_PROJECT_SIZE_BYTES: Long = 200 * 1024 * 1024
2121

2222
val CLIENT_ERROR_MESSAGES = setOf(
23-
"Improperly formed request",
24-
"Resource not found",
2523
"StartTaskAssistCodeGeneration reached for this month.",
2624
"The folder you chose did not contain any source files in a supported language. Choose another folder and try again.",
2725
"reached the quota for number of iterations on code generation."

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/FeatureDevExceptions.kt

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,52 +24,78 @@ open class FeatureDevException(override val message: String?, val operation: Str
2424
}
2525
}
2626

27+
/**
28+
* Exceptions extending this class are considered "errors" in service metrics.
29+
*/
30+
open class ClientException(message: String, operation: String, desc: String?, cause: Throwable? = null) :
31+
FeatureDevException(message, operation, desc, cause)
32+
33+
/**
34+
* Errors extending this class are considered "faults" in service metrics.
35+
*/
36+
open class ServiceException(message: String, operation: String, desc: String?, cause: Throwable? = null) :
37+
FeatureDevException(message, operation, desc, cause)
38+
39+
/**
40+
* Errors extending this class are considered "LLM failures" in service metrics.
41+
*/
42+
open class LlmException(message: String, operation: String, desc: String?, cause: Throwable? = null) :
43+
FeatureDevException(message, operation, desc, cause)
44+
45+
object ApiException {
46+
fun of(statusCode: Int, message: String, operation: String, desc: String?, cause: Throwable? = null): FeatureDevException =
47+
when (statusCode in 400..499) {
48+
true -> ClientException(message, operation, desc, cause)
49+
false -> ServiceException(message, operation, desc, cause)
50+
}
51+
}
52+
2753
class NoChangeRequiredException(operation: String, desc: String?, cause: Throwable? = null) :
28-
FeatureDevException(message("amazonqFeatureDev.exception.no_change_required_exception"), operation, desc, cause)
54+
ClientException(message("amazonqFeatureDev.exception.no_change_required_exception"), operation, desc, cause)
2955

3056
class EmptyPatchException(operation: String, desc: String?, cause: Throwable? = null) :
31-
FeatureDevException(message("amazonqFeatureDev.exception.guardrails"), operation, desc, cause)
57+
LlmException(message("amazonqFeatureDev.exception.guardrails"), operation, desc, cause)
3258

3359
class ContentLengthException(
3460
override val message: String = message("amazonqFeatureDev.content_length.error_text"),
3561
operation: String,
3662
desc: String?,
3763
cause: Throwable? = null,
3864
) :
39-
RepoSizeError, FeatureDevException(message, operation, desc, cause)
65+
RepoSizeError, ClientException(message, operation, desc, cause)
4066

4167
class ZipFileCorruptedException(operation: String, desc: String?, cause: Throwable? = null) :
42-
FeatureDevException("The zip file is corrupted", operation, desc, cause)
68+
ServiceException("The zip file is corrupted", operation, desc, cause)
4369

4470
class UploadURLExpired(operation: String, desc: String?, cause: Throwable? = null) :
45-
FeatureDevException(message("amazonqFeatureDev.exception.upload_url_expiry"), operation, desc, cause)
71+
ClientException(message("amazonqFeatureDev.exception.upload_url_expiry"), operation, desc, cause)
4672

4773
class CodeIterationLimitException(operation: String, desc: String?, cause: Throwable? = null) :
48-
FeatureDevException(message("amazonqFeatureDev.code_generation.iteration_limit.error_text"), operation, desc, cause)
74+
ClientException(message("amazonqFeatureDev.code_generation.iteration_limit.error_text"), operation, desc, cause)
4975

5076
class MonthlyConversationLimitError(message: String, operation: String, desc: String?, cause: Throwable? = null) :
51-
FeatureDevException(message, operation, desc, cause)
77+
ClientException(message, operation, desc, cause)
5278

5379
class GuardrailsException(operation: String, desc: String?, cause: Throwable? = null) :
54-
FeatureDevException(message("amazonqFeatureDev.exception.guardrails"), operation, desc, cause)
80+
ClientException(message("amazonqFeatureDev.exception.guardrails"), operation, desc, cause)
5581

5682
class PromptRefusalException(operation: String, desc: String?, cause: Throwable? = null) :
57-
FeatureDevException(message("amazonqFeatureDev.exception.prompt_refusal"), operation, desc, cause)
83+
ClientException(message("amazonqFeatureDev.exception.prompt_refusal"), operation, desc, cause)
5884

5985
class ThrottlingException(operation: String, desc: String?, cause: Throwable? = null) :
60-
FeatureDevException(message("amazonqFeatureDev.exception.throttling"), operation, desc, cause)
86+
ClientException(message("amazonqFeatureDev.exception.throttling"), operation, desc, cause)
6187

6288
class ExportParseException(operation: String, desc: String?, cause: Throwable? = null) :
63-
FeatureDevException(message("amazonqFeatureDev.exception.export_parsing_error"), operation, desc, cause)
89+
ServiceException(message("amazonqFeatureDev.exception.export_parsing_error"), operation, desc, cause)
6490

6591
class CodeGenerationException(operation: String, desc: String?, cause: Throwable? = null) :
66-
FeatureDevException(message("amazonqFeatureDev.code_generation.failed_generation"), operation, desc, cause)
92+
ServiceException(message("amazonqFeatureDev.code_generation.failed_generation"), operation, desc, cause)
6793

6894
class UploadCodeException(operation: String, desc: String?, cause: Throwable? = null) :
69-
FeatureDevException(message("amazonqFeatureDev.exception.upload_code"), operation, desc, cause)
95+
ServiceException(message("amazonqFeatureDev.exception.upload_code"), operation, desc, cause)
7096

7197
class ConversationIdNotFoundException(operation: String, desc: String?, cause: Throwable? = null) :
72-
FeatureDevException(message("amazonqFeatureDev.exception.conversation_not_found"), operation, desc, cause)
98+
ServiceException(message("amazonqFeatureDev.exception.conversation_not_found"), operation, desc, cause)
7399

74100
val denyListedErrors = arrayOf("Deserialization error", "Inaccessible host", "UnknownHost")
75101
fun createUserFacingErrorMessage(message: String?): String? =

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevControllerExtensions.kt

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,11 @@ import com.intellij.notification.NotificationAction
77
import software.aws.toolkits.jetbrains.services.amazonq.messages.MessagePublisher
88
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.CLIENT_ERROR_MESSAGES
99
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.CODE_GENERATION_RETRY_LIMIT
10-
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.CodeIterationLimitException
11-
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ContentLengthException
12-
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.EmptyPatchException
13-
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.GuardrailsException
10+
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ClientException
11+
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.LlmException
1412
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.MetricDataOperationName
1513
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.MetricDataResult
16-
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.MonthlyConversationLimitError
17-
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.NoChangeRequiredException
18-
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.PromptRefusalException
19-
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ThrottlingException
20-
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ZipFileCorruptedException
14+
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ServiceException
2115
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.FeatureDevMessageType
2216
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.FollowUp
2317
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.FollowUpStatusType
@@ -158,43 +152,34 @@ suspend fun FeatureDevController.onCodeGeneration(
158152
messenger.sendSystemPrompt(tabId = tabId, followUp = getFollowUpOptions(session.sessionState.phase, InsertAction.ALL))
159153
messenger.sendUpdatePlaceholder(tabId = tabId, newPlaceholder = message("amazonqFeatureDev.placeholder.after_code_generation"))
160154
} catch (err: Exception) {
155+
val metricDataResult: MetricDataResult
161156
when (err) {
162-
is GuardrailsException,
163-
is NoChangeRequiredException,
164-
is PromptRefusalException,
165-
is ThrottlingException,
166-
is CodeIterationLimitException,
167-
is MonthlyConversationLimitError,
168-
is ContentLengthException,
169-
is ZipFileCorruptedException,
157+
is ClientException,
170158
-> {
171-
session.sendMetricDataTelemetry(
172-
MetricDataOperationName.EndCodeGeneration,
173-
MetricDataResult.Error
174-
)
159+
metricDataResult = MetricDataResult.Error
160+
}
161+
162+
is LlmException -> {
163+
metricDataResult = MetricDataResult.LlmFailure
175164
}
176-
is EmptyPatchException -> {
177-
session.sendMetricDataTelemetry(
178-
MetricDataOperationName.EndCodeGeneration,
179-
MetricDataResult.LlmFailure
180-
)
165+
166+
is ServiceException -> {
167+
metricDataResult = MetricDataResult.Fault
181168
}
169+
182170
else -> {
183171
val errorMessage = err.message.orEmpty()
184-
185-
if (CLIENT_ERROR_MESSAGES.any { errorMessage.contains(it) }) {
186-
session.sendMetricDataTelemetry(
187-
MetricDataOperationName.EndCodeGeneration,
188-
MetricDataResult.Error
189-
)
172+
metricDataResult = if (CLIENT_ERROR_MESSAGES.any { errorMessage.contains(it) }) {
173+
MetricDataResult.Error
190174
} else {
191-
session.sendMetricDataTelemetry(
192-
MetricDataOperationName.EndCodeGeneration,
193-
MetricDataResult.Fault
194-
)
175+
MetricDataResult.Fault
195176
}
196177
}
197178
}
179+
session.sendMetricDataTelemetry(
180+
MetricDataOperationName.EndCodeGeneration,
181+
metricDataResult
182+
)
198183
throw err
199184
} finally {
200185
if (session.sessionState.token

0 commit comments

Comments
 (0)