@@ -525,6 +525,102 @@ Your admin might have disabled the access. Contact them to enable the Preview Re
525525 expect ( result . current . proQuotaRequest ) . toBeNull ( ) ;
526526 } ) ;
527527
528+ it ( 'should handle ModelNotFoundError with Vertex AI by displaying region-specific availability message and documentation link' , async ( ) => {
529+ vi . spyOn ( mockConfig , 'getContentGeneratorConfig' ) . mockReturnValue ( {
530+ authType : AuthType . USE_VERTEX_AI ,
531+ } ) ;
532+ vi . stubEnv ( 'GOOGLE_CLOUD_LOCATION' , 'us-central1' ) ;
533+
534+ const { result } = await renderHook ( ( ) =>
535+ useQuotaAndFallback ( {
536+ config : mockConfig ,
537+ historyManager : mockHistoryManager ,
538+ userTier : UserTierId . FREE ,
539+ setModelSwitchedFromQuotaError : mockSetModelSwitchedFromQuotaError ,
540+ onShowAuthSelection : mockOnShowAuthSelection ,
541+ paidTier : null ,
542+ settings : mockSettings ,
543+ } ) ,
544+ ) ;
545+
546+ const handler = setFallbackHandlerSpy . mock
547+ . calls [ 0 ] [ 0 ] as FallbackModelHandler ;
548+
549+ let promise : Promise < FallbackIntent | null > ;
550+ const error = new ModelNotFoundError ( 'model not found' , 404 ) ;
551+
552+ act ( ( ) => {
553+ promise = handler ( 'gemini-3.5-flash' , 'gemini-1.5-flash' , error ) ;
554+ } ) ;
555+
556+ const request = result . current . proQuotaRequest ;
557+ expect ( request ) . not . toBeNull ( ) ;
558+ expect ( request ?. failedModel ) . toBe ( 'gemini-3.5-flash' ) ;
559+ expect ( request ?. isModelNotFoundError ) . toBe ( true ) ;
560+
561+ const message = request ! . message ;
562+ expect ( message ) . toBe (
563+ `Model "gemini-3.5-flash" is not available in region "us-central1".\n` +
564+ `To see which models are available in this region, please visit:\n` +
565+ `https://cloud.google.com/vertex-ai/generative-ai/docs/learn/locations\n` +
566+ `/model to switch models.` ,
567+ ) ;
568+
569+ act ( ( ) => {
570+ result . current . handleProQuotaChoice ( 'retry_always' ) ;
571+ } ) ;
572+
573+ const intent = await promise ! ;
574+ expect ( intent ) . toBe ( 'retry_always' ) ;
575+ } ) ;
576+
577+ it ( 'should handle ModelNotFoundError with Vertex AI and invalid model by displaying generic not found error message' , async ( ) => {
578+ vi . spyOn ( mockConfig , 'getContentGeneratorConfig' ) . mockReturnValue ( {
579+ authType : AuthType . USE_VERTEX_AI ,
580+ } ) ;
581+ vi . stubEnv ( 'GOOGLE_CLOUD_LOCATION' , 'us-central1' ) ;
582+
583+ const { result } = await renderHook ( ( ) =>
584+ useQuotaAndFallback ( {
585+ config : mockConfig ,
586+ historyManager : mockHistoryManager ,
587+ userTier : UserTierId . FREE ,
588+ setModelSwitchedFromQuotaError : mockSetModelSwitchedFromQuotaError ,
589+ onShowAuthSelection : mockOnShowAuthSelection ,
590+ paidTier : null ,
591+ settings : mockSettings ,
592+ } ) ,
593+ ) ;
594+
595+ const handler = setFallbackHandlerSpy . mock
596+ . calls [ 0 ] [ 0 ] as FallbackModelHandler ;
597+
598+ let promise : Promise < FallbackIntent | null > ;
599+ const error = new ModelNotFoundError ( 'model not found' , 404 ) ;
600+
601+ act ( ( ) => {
602+ promise = handler ( 'invalid-model-name' , 'gemini-1.5-flash' , error ) ;
603+ } ) ;
604+
605+ const request = result . current . proQuotaRequest ;
606+ expect ( request ) . not . toBeNull ( ) ;
607+ expect ( request ?. failedModel ) . toBe ( 'invalid-model-name' ) ;
608+ expect ( request ?. isModelNotFoundError ) . toBe ( true ) ;
609+
610+ const message = request ! . message ;
611+ expect ( message ) . toBe (
612+ `Model "invalid-model-name" was not found or is invalid.\n` +
613+ `/model to switch models.` ,
614+ ) ;
615+
616+ act ( ( ) => {
617+ result . current . handleProQuotaChoice ( 'retry_always' ) ;
618+ } ) ;
619+
620+ const intent = await promise ! ;
621+ expect ( intent ) . toBe ( 'retry_always' ) ;
622+ } ) ;
623+
528624 it ( 'should handle ModelNotFoundError with invalid model correctly' , async ( ) => {
529625 const { result } = await renderHook ( ( ) =>
530626 useQuotaAndFallback ( {
0 commit comments