Skip to content

Commit f5bc8c2

Browse files
authored
fix(amazonq): filter out frequent client error from codegeneration telemetry (#6521)
## Problem We are mistakenly counting several client-side failures as service faults, which is affecting our availability metrics. ## Solution Exclude frequent client errors from faults, they should be errors. there are multiple layers of errors, some of those are categorized to toolkit level errors, for example this part: ``` case MonthlyConversationLimitError.name: case CodeIterationLimitError.name: case PromptRefusalException.name: case NoChangeRequiredException.name: ``` Others are defaulting to ToolkitError with messages. Ideally we should add more error models to toolkit, but for now to make a quick fix, I just looked into the error msg, similar to what we do here: https://github.com/aws/aws-toolkit-vscode/blob/02d21a2fafc7479fb398ea078aa3e3adf7c62e7a/packages/core/src/amazonqFeatureDev/client/featureDev.ts#L198 --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Co-authored-by: Yuxin Lin <linyuxi@amazon.com>
1 parent 29c4048 commit f5bc8c2

File tree

5 files changed

+37
-7
lines changed

5 files changed

+37
-7
lines changed

packages/core/src/amazonqFeatureDev/client/featureDev.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ServiceOptions } from '../../shared/awsClientBuilder'
1010
import globals from '../../shared/extensionGlobals'
1111
import { getLogger } from '../../shared/logger/logger'
1212
import * as FeatureDevProxyClient from './featuredevproxyclient'
13-
import { featureName } from '../constants'
13+
import { featureName, startTaskAssistLimitReachedMessage } from '../constants'
1414
import { CodeReference } from '../../amazonq/webview/ui/connector'
1515
import {
1616
ApiError,
@@ -185,10 +185,7 @@ export class FeatureDevClient {
185185
)
186186
if (isAwsError(e)) {
187187
// API Front-end will throw Throttling if conversation limit is reached. API Front-end monitors StartCodeGeneration for throttling
188-
if (
189-
e.code === 'ThrottlingException' &&
190-
e.message.includes('StartTaskAssistCodeGeneration reached for this month.')
191-
) {
188+
if (e.code === 'ThrottlingException' && e.message.includes(startTaskAssistLimitReachedMessage)) {
192189
throw new MonthlyConversationLimitError(e.message)
193190
}
194191
// BE service will throw ServiceQuota if code generation iteration limit is reached

packages/core/src/amazonqFeatureDev/constants.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ export const generateDevFilePrompt =
2020
// Max allowed size for file collection
2121
export const maxRepoSizeBytes = 200 * 1024 * 1024
2222

23+
export const startCodeGenClientErrorMessages = ['Improperly formed request', 'Resource not found']
24+
export const startTaskAssistLimitReachedMessage = 'StartTaskAssistCodeGeneration reached for this month.'
25+
export const clientErrorMessages = [
26+
'The folder you chose did not contain any source files in a supported language. Choose another folder and try again.',
27+
]
28+
2329
// License text that's used in codewhisperer reference log
2430
export const referenceLogText = (reference: CodeReference) =>
2531
`[${new Date().toLocaleString()}] Accepted recommendation from Amazon Q. Code provided with reference under <a href="${LicenseUtil.getLicenseHtml(

packages/core/src/amazonqFeatureDev/controllers/chat/controller.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
createUserFacingErrorMessage,
1616
denyListedErrors,
1717
FeatureDevServiceError,
18+
isAPIClientError,
1819
MonthlyConversationLimitError,
1920
NoChangeRequiredException,
2021
PrepareRepoFailedError,
@@ -555,12 +556,18 @@ export class FeatureDevController {
555556
result = MetricDataResult.Fault
556557
}
557558
break
559+
case MonthlyConversationLimitError.name:
560+
case CodeIterationLimitError.name:
558561
case PromptRefusalException.name:
559562
case NoChangeRequiredException.name:
560563
result = MetricDataResult.Error
561564
break
562565
default:
563-
result = MetricDataResult.Fault
566+
if (isAPIClientError(err)) {
567+
result = MetricDataResult.Error
568+
} else {
569+
result = MetricDataResult.Fault
570+
}
564571
break
565572
}
566573

packages/core/src/amazonqFeatureDev/errors.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
*/
55

66
import { ToolkitError } from '../shared/errors'
7-
import { featureName } from './constants'
7+
import {
8+
featureName,
9+
clientErrorMessages,
10+
startCodeGenClientErrorMessages,
11+
startTaskAssistLimitReachedMessage,
12+
} from './constants'
813
import { uploadCodeError } from './userFacingText'
914
import { i18n } from '../shared/i18n-helper'
1015

@@ -140,3 +145,12 @@ export function createUserFacingErrorMessage(message: string) {
140145
}
141146
return message
142147
}
148+
149+
export function isAPIClientError(error: { code?: string; message: string }): boolean {
150+
return (
151+
(error.code === 'StartCodeGenerationFailed' &&
152+
startCodeGenClientErrorMessages.some((msg: string) => error.message.includes(msg))) ||
153+
clientErrorMessages.some((msg: string) => error.message.includes(msg)) ||
154+
error.message.includes(startTaskAssistLimitReachedMessage)
155+
)
156+
}

packages/core/src/test/amazonqFeatureDev/controllers/chat/controller.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
ContentLengthError,
2525
createUserFacingErrorMessage,
2626
FeatureDevServiceError,
27+
isAPIClientError,
2728
MonthlyConversationLimitError,
2829
NoChangeRequiredException,
2930
PrepareRepoFailedError,
@@ -471,12 +472,17 @@ describe('Controller', () => {
471472
['EmptyPatchException', MetricDataResult.LlmFailure],
472473
[PromptRefusalException.name, MetricDataResult.Error],
473474
[NoChangeRequiredException.name, MetricDataResult.Error],
475+
[MonthlyConversationLimitError.name, MetricDataResult.Error],
476+
[CodeIterationLimitError.name, MetricDataResult.Error],
474477
])
475478

476479
function getMetricResult(error: ToolkitError): MetricDataResult {
477480
if (error instanceof FeatureDevServiceError && error.code) {
478481
return errorResultMapping.get(error.code) ?? MetricDataResult.Error
479482
}
483+
if (isAPIClientError(error)) {
484+
return MetricDataResult.Error
485+
}
480486
return errorResultMapping.get(error.constructor.name) ?? MetricDataResult.Fault
481487
}
482488

0 commit comments

Comments
 (0)