Skip to content

Commit 483e717

Browse files
committed
refactor(dev): remove errorName from Amazon Q feature development error classes
1 parent 9fecde2 commit 483e717

File tree

3 files changed

+117
-22
lines changed

3 files changed

+117
-22
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,15 @@ export class FeatureDevController {
214214
)
215215

216216
let defaultMessage
217-
const isDenyListedError = denyListedErrors.some((err) => errorMessage.includes(err))
217+
const isDenyListedError = denyListedErrors.some((denyListedError) => err.message.includes(denyListedError))
218218

219219
switch (err.constructor.name) {
220220
case ContentLengthError.name:
221221
this.messenger.sendAnswer({
222222
type: 'answer',
223223
tabID: message.tabID,
224224
message: err.message + messageWithConversationId(session?.conversationIdUnsafe),
225+
canBeVoted: true,
225226
})
226227
this.messenger.sendAnswer({
227228
type: 'system-prompt',
@@ -268,6 +269,7 @@ export class FeatureDevController {
268269
type: 'answer',
269270
tabID: message.tabID,
270271
message: err.message + messageWithConversationId(session?.conversationIdUnsafe),
272+
canBeVoted: true,
271273
})
272274
this.messenger.sendAnswer({
273275
type: 'system-prompt',

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export class Messenger {
8585
type: 'answer',
8686
tabID: tabID,
8787
message: showDefaultMessage ? errorMessage : i18n('AWS.amazonq.featureDev.error.technicalDifficulties'),
88+
canBeVoted: true,
8889
})
8990
this.sendFeedback(tabID)
9091
return

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

Lines changed: 113 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,27 @@ import { Session } from '../../../../amazonqFeatureDev/session/session'
1414
import { Prompter } from '../../../../shared/ui/prompter'
1515
import { assertTelemetry, toFile } from '../../../testUtil'
1616
import {
17+
CodeIterationLimitError,
18+
ContentLengthError,
19+
createUserFacingErrorMessage,
20+
FeatureDevServiceError,
21+
MonthlyConversationLimitError,
1722
NoChangeRequiredException,
23+
PrepareRepoFailedError,
24+
PromptRefusalException,
1825
SelectedFolderNotInWorkspaceFolderError,
26+
TabIdNotFoundError,
27+
UploadCodeError,
1928
UploadURLExpired,
29+
UserMessageNotFoundError,
30+
ZipFileError,
2031
} from '../../../../amazonqFeatureDev/errors'
2132
import { CodeGenState, PrepareCodeGenState } from '../../../../amazonqFeatureDev/session/sessionState'
2233
import { FeatureDevClient } from '../../../../amazonqFeatureDev/client/featureDev'
2334
import { createAmazonQUri } from '../../../../amazonq/commons/diff'
2435
import { AuthUtil } from '../../../../codewhisperer'
36+
import { featureName, messageWithConversationId } from '../../../../amazonqFeatureDev'
37+
import { i18n } from '../../../../shared/i18n-helper'
2538

2639
let mockGetCodeGeneration: sinon.SinonStub
2740
describe('Controller', () => {
@@ -210,7 +223,6 @@ describe('Controller', () => {
210223
})
211224

212225
it('accepts valid source folders under a workspace root', async () => {
213-
const controllerSetup = await createController()
214226
sinon.stub(controllerSetup.sessionStorage, 'getSession').resolves(session)
215227
sinon.stub(vscode.workspace, 'getWorkspaceFolder').returns(controllerSetup.workspaceFolder)
216228
const expectedSourceRoot = path.join(controllerSetup.workspaceFolder.uri.fsPath, 'src')
@@ -386,33 +398,113 @@ describe('Controller', () => {
386398
}
387399

388400
describe('processErrorChatMessage', function () {
389-
async function verifyException(error: Error, message?: string) {
401+
const runs = [
402+
{ name: 'ContentLengthError', error: new ContentLengthError() },
403+
{
404+
name: 'MonthlyConversationLimitError',
405+
error: new MonthlyConversationLimitError('Service Quota Exceeded'),
406+
},
407+
{
408+
name: 'FeatureDevServiceError',
409+
error: new FeatureDevServiceError(
410+
i18n('AWS.amazonq.featureDev.error.codeGen.default'),
411+
'GuardrailsException'
412+
),
413+
},
414+
{ name: 'UploadCodeError', error: new UploadCodeError('403: Forbiden') },
415+
{ name: 'UserMessageNotFoundError', error: new UserMessageNotFoundError() },
416+
{ name: 'TabIdNotFoundError', error: new TabIdNotFoundError() },
417+
{ name: 'PrepareRepoFailedError', error: new PrepareRepoFailedError() },
418+
{ name: 'PromptRefusalException', error: new PromptRefusalException() },
419+
{ name: 'ZipFileError', error: new ZipFileError() },
420+
{ name: 'CodeIterationLimitError', error: new CodeIterationLimitError() },
421+
{ name: 'UploadURLExpired', error: new UploadURLExpired() },
422+
{ name: 'NoChangeRequiredException', error: new NoChangeRequiredException() },
423+
{ name: 'default', error: new Error() },
424+
]
425+
426+
function createTestErrorMessage(message: string) {
427+
return createUserFacingErrorMessage(`${featureName} request failed: ${message}`)
428+
}
429+
430+
async function verifyException(error: Error) {
390431
sinon.stub(session, 'preloader').throws(error)
391432
const sendAnswerSpy = sinon.stub(controllerSetup.messenger, 'sendAnswer')
433+
const sendErrorMessageSpy = sinon.stub(controllerSetup.messenger, 'sendErrorMessage')
434+
const sendMonthlyLimitErrorSpy = sinon.stub(controllerSetup.messenger, 'sendMonthlyLimitError')
392435

393436
await fireChatMessage()
394437

395-
assert.strictEqual(
396-
sendAnswerSpy.calledWith({
397-
type: 'answer',
398-
tabID,
399-
message: message ?? error.message,
400-
canBeVoted: true,
401-
}),
402-
true
403-
)
438+
switch (error.constructor.name) {
439+
case ContentLengthError.name:
440+
assert.ok(
441+
sendAnswerSpy.calledWith({
442+
type: 'answer',
443+
tabID,
444+
message: error.message + messageWithConversationId(session?.conversationIdUnsafe),
445+
canBeVoted: true,
446+
})
447+
)
448+
break
449+
case MonthlyConversationLimitError.name:
450+
assert.ok(sendMonthlyLimitErrorSpy.calledWith(tabID))
451+
break
452+
case FeatureDevServiceError.name:
453+
case UploadCodeError.name:
454+
case UserMessageNotFoundError.name:
455+
case TabIdNotFoundError.name:
456+
case PrepareRepoFailedError.name:
457+
assert.ok(
458+
sendErrorMessageSpy.calledWith(
459+
createTestErrorMessage(error.message),
460+
tabID,
461+
session?.retries,
462+
session?.conversationIdUnsafe
463+
)
464+
)
465+
break
466+
case PromptRefusalException.name:
467+
case ZipFileError.name:
468+
assert.ok(
469+
sendErrorMessageSpy.calledWith(
470+
createTestErrorMessage(error.message),
471+
tabID,
472+
0,
473+
session?.conversationIdUnsafe,
474+
true
475+
)
476+
)
477+
break
478+
case NoChangeRequiredException.name:
479+
case CodeIterationLimitError.name:
480+
case UploadURLExpired.name:
481+
assert.ok(
482+
sendAnswerSpy.calledWith({
483+
type: 'answer',
484+
tabID,
485+
message: error.message,
486+
canBeVoted: true,
487+
})
488+
)
489+
break
490+
default:
491+
assert.ok(
492+
sendErrorMessageSpy.calledWith(
493+
i18n('AWS.amazonq.featureDev.error.codeGen.default'),
494+
tabID,
495+
session?.retries,
496+
session?.conversationIdUnsafe,
497+
true
498+
)
499+
)
500+
break
501+
}
404502
}
405503

406-
it('should handle NoChangeRequiredException', async function () {
407-
const noChangeRequiredException = new NoChangeRequiredException()
408-
409-
await verifyException(noChangeRequiredException)
410-
})
411-
412-
it('should handle UploadURLExpired', async function () {
413-
const uploadURLExpired = new UploadURLExpired()
414-
415-
await verifyException(uploadURLExpired)
504+
runs.forEach((run) => {
505+
it(`should handle ${run.name}`, async function () {
506+
await verifyException(run.error)
507+
})
416508
})
417509
})
418510
})

0 commit comments

Comments
 (0)