@@ -9,7 +9,13 @@ import * as path from 'path'
99import sinon from 'sinon'
1010import { waitUntil } from '../../../../shared/utilities/timeoutUtils'
1111import { ControllerSetup , createController , createSession , generateVirtualMemoryUri } from '../../utils'
12- import { CurrentWsFolders , DeletedFileInfo , NewFileInfo } from '../../../../amazonqFeatureDev/types'
12+ import {
13+ CurrentWsFolders ,
14+ DeletedFileInfo ,
15+ MetricDataOperationName ,
16+ MetricDataResult ,
17+ NewFileInfo ,
18+ } from '../../../../amazonqFeatureDev/types'
1319import { Session } from '../../../../amazonqFeatureDev/session/session'
1420import { Prompter } from '../../../../shared/ui/prompter'
1521import { assertTelemetry , toFile } from '../../../testUtil'
@@ -36,6 +42,7 @@ import { AuthUtil } from '../../../../codewhisperer'
3642import { featureDevScheme , featureName , messageWithConversationId } from '../../../../amazonqFeatureDev'
3743import { i18n } from '../../../../shared/i18n-helper'
3844import { FollowUpTypes } from '../../../../amazonq/commons/types'
45+ import { ToolkitError } from '../../../../shared'
3946
4047let mockGetCodeGeneration : sinon . SinonStub
4148describe ( 'Controller' , ( ) => {
@@ -395,6 +402,46 @@ describe('Controller', () => {
395402 } )
396403
397404 describe ( 'processUserChatMessage' , function ( ) {
405+ // TODO: fix disablePreviousFileList error
406+ const runs = [
407+ { name : 'ContentLengthError' , error : new ContentLengthError ( ) } ,
408+ {
409+ name : 'MonthlyConversationLimitError' ,
410+ error : new MonthlyConversationLimitError ( 'Service Quota Exceeded' ) ,
411+ } ,
412+ {
413+ name : 'FeatureDevServiceErrorGuardrailsException' ,
414+ error : new FeatureDevServiceError (
415+ i18n ( 'AWS.amazonq.featureDev.error.codeGen.default' ) ,
416+ 'GuardrailsException'
417+ ) ,
418+ } ,
419+ {
420+ name : 'FeatureDevServiceErrorEmptyPatchException' ,
421+ error : new FeatureDevServiceError (
422+ i18n ( 'AWS.amazonq.featureDev.error.throttling' ) ,
423+ 'EmptyPatchException'
424+ ) ,
425+ } ,
426+ {
427+ name : 'FeatureDevServiceErrorThrottlingException' ,
428+ error : new FeatureDevServiceError (
429+ i18n ( 'AWS.amazonq.featureDev.error.codeGen.default' ) ,
430+ 'ThrottlingException'
431+ ) ,
432+ } ,
433+ { name : 'UploadCodeError' , error : new UploadCodeError ( '403: Forbiden' ) } ,
434+ { name : 'UserMessageNotFoundError' , error : new UserMessageNotFoundError ( ) } ,
435+ { name : 'TabIdNotFoundError' , error : new TabIdNotFoundError ( ) } ,
436+ { name : 'PrepareRepoFailedError' , error : new PrepareRepoFailedError ( ) } ,
437+ { name : 'PromptRefusalException' , error : new PromptRefusalException ( ) } ,
438+ { name : 'ZipFileError' , error : new ZipFileError ( ) } ,
439+ { name : 'CodeIterationLimitError' , error : new CodeIterationLimitError ( ) } ,
440+ { name : 'UploadURLExpired' , error : new UploadURLExpired ( ) } ,
441+ { name : 'NoChangeRequiredException' , error : new NoChangeRequiredException ( ) } ,
442+ { name : 'default' , error : new ToolkitError ( 'Default' , { code : 'Default' } ) } ,
443+ ]
444+
398445 async function fireChatMessage ( ) {
399446 const getSessionStub = sinon . stub ( controllerSetup . sessionStorage , 'getSession' ) . resolves ( session )
400447
@@ -410,38 +457,63 @@ describe('Controller', () => {
410457 } , { } )
411458 }
412459
413- describe ( 'processErrorChatMessage' , function ( ) {
414- // TODO: fix disablePreviousFileList error
415- const runs = [
416- { name : 'ContentLengthError' , error : new ContentLengthError ( ) } ,
417- {
418- name : 'MonthlyConversationLimitError' ,
419- error : new MonthlyConversationLimitError ( 'Service Quota Exceeded' ) ,
420- } ,
421- {
422- name : 'FeatureDevServiceError' ,
423- error : new FeatureDevServiceError (
424- i18n ( 'AWS.amazonq.featureDev.error.codeGen.default' ) ,
425- 'GuardrailsException'
426- ) ,
427- } ,
428- { name : 'UploadCodeError' , error : new UploadCodeError ( '403: Forbiden' ) } ,
429- { name : 'UserMessageNotFoundError' , error : new UserMessageNotFoundError ( ) } ,
430- { name : 'TabIdNotFoundError' , error : new TabIdNotFoundError ( ) } ,
431- { name : 'PrepareRepoFailedError' , error : new PrepareRepoFailedError ( ) } ,
432- { name : 'PromptRefusalException' , error : new PromptRefusalException ( ) } ,
433- { name : 'ZipFileError' , error : new ZipFileError ( ) } ,
434- { name : 'CodeIterationLimitError' , error : new CodeIterationLimitError ( ) } ,
435- { name : 'UploadURLExpired' , error : new UploadURLExpired ( ) } ,
436- { name : 'NoChangeRequiredException' , error : new NoChangeRequiredException ( ) } ,
437- { name : 'default' , error : new Error ( ) } ,
438- ]
460+ describe ( 'onCodeGeneration' , function ( ) {
461+ async function verifyException ( error : ToolkitError ) {
462+ sinon . stub ( session , 'preloader' ) . resolves ( )
463+ sinon . stub ( session , 'send' ) . throws ( error )
464+ const sendMetricDataTelemetrySpy = sinon . stub ( session , 'sendMetricDataTelemetry' )
465+
466+ await fireChatMessage ( )
467+
468+ sendMetricDataTelemetrySpy . calledWith (
469+ MetricDataOperationName . START_CODE_GENERATION ,
470+ MetricDataResult . SUCCESS
471+ )
439472
473+ switch ( error . constructor . name ) {
474+ case FeatureDevServiceError . name :
475+ if ( error . code === 'EmptyPatchException' ) {
476+ sendMetricDataTelemetrySpy . calledWith (
477+ MetricDataOperationName . END_CODE_GENERATION ,
478+ MetricDataResult . LLMFAILURE
479+ )
480+ } else {
481+ sendMetricDataTelemetrySpy . calledWith (
482+ MetricDataOperationName . END_CODE_GENERATION ,
483+ MetricDataResult . ERROR
484+ )
485+ }
486+ break
487+ case PromptRefusalException . name :
488+ case NoChangeRequiredException . name :
489+ sendMetricDataTelemetrySpy . calledWith (
490+ MetricDataOperationName . END_CODE_GENERATION ,
491+ MetricDataResult . ERROR
492+ )
493+ break
494+ default :
495+ sendMetricDataTelemetrySpy . calledWith (
496+ MetricDataOperationName . END_CODE_GENERATION ,
497+ MetricDataResult . FAULT
498+ )
499+
500+ break
501+ }
502+ }
503+
504+ runs . forEach ( ( run ) => {
505+ it ( `sends operation telemetry on ${ run . name } ` , async function ( ) {
506+ await verifyException ( run . error )
507+ } )
508+ } )
509+ } )
510+
511+ describe ( 'processErrorChatMessage' , function ( ) {
440512 function createTestErrorMessage ( message : string ) {
441513 return createUserFacingErrorMessage ( `${ featureName } request failed: ${ message } ` )
442514 }
443515
444- async function verifyException ( error : Error ) {
516+ async function verifyException ( error : ToolkitError ) {
445517 sinon . stub ( session , 'preloader' ) . throws ( error )
446518 const sendAnswerSpy = sinon . stub ( controllerSetup . messenger , 'sendAnswer' )
447519 const sendErrorMessageSpy = sinon . stub ( controllerSetup . messenger , 'sendErrorMessage' )
0 commit comments