@@ -14,14 +14,27 @@ import { Session } from '../../../../amazonqFeatureDev/session/session'
1414import { Prompter } from '../../../../shared/ui/prompter'
1515import { assertTelemetry , toFile } from '../../../testUtil'
1616import {
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'
2132import { CodeGenState , PrepareCodeGenState } from '../../../../amazonqFeatureDev/session/sessionState'
2233import { FeatureDevClient } from '../../../../amazonqFeatureDev/client/featureDev'
2334import { createAmazonQUri } from '../../../../amazonq/commons/diff'
2435import { AuthUtil } from '../../../../codewhisperer'
36+ import { featureName , messageWithConversationId } from '../../../../amazonqFeatureDev'
37+ import { i18n } from '../../../../shared/i18n-helper'
2538
2639let mockGetCodeGeneration : sinon . SinonStub
2740describe ( '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