@@ -1054,20 +1054,52 @@ Remember: Be intelligent about filtering - only provide detailed responses when
10541054 } ;
10551055 } catch ( error ) {
10561056 const errorAnalysis = this . analyzeError ( error ) ;
1057- logger . error ( 'Connection test failed' , {
1057+ logger . error ( 'Connection test failed' , {
10581058 error : error . message ,
10591059 errorAnalysis
10601060 } ) ;
1061-
1062- return {
1063- success : false ,
1064- error : error . message ,
1061+
1062+ // Map raw SDK errors to user-friendly messages. The wizard only
1063+ // surfaces `error`, so any raw "[GoogleGenerativeAI Error]: ..."
1064+ // string would land in the UI verbatim.
1065+ const friendlyError = this . _friendlyTestError ( error , errorAnalysis ) ;
1066+
1067+ return {
1068+ success : false ,
1069+ error : friendlyError ,
1070+ errorType : errorAnalysis ?. type || 'UNKNOWN' ,
10651071 errorAnalysis,
10661072 networkConnectivity : await this . checkNetworkConnectivity ( ) . catch ( ( ) => null )
10671073 } ;
10681074 }
10691075 }
10701076
1077+ /**
1078+ * Translate raw SDK / network errors into something a user can act on.
1079+ */
1080+ _friendlyTestError ( error , analysis ) {
1081+ const type = analysis ?. type ;
1082+ const raw = ( error ?. message || '' ) . toLowerCase ( ) ;
1083+
1084+ if ( type === 'NETWORK_ERROR' || raw . includes ( 'fetch failed' ) || raw . includes ( 'enotfound' ) ) {
1085+ return 'Cannot reach Google servers. Check your internet connection, firewall, or VPN settings.' ;
1086+ }
1087+ if ( type === 'AUTH_ERROR' || raw . includes ( 'api key' ) || raw . includes ( '401' ) || raw . includes ( '403' ) ) {
1088+ return 'Invalid API key or insufficient permissions. Double-check the key at aistudio.google.com/apikey.' ;
1089+ }
1090+ if ( type === 'RATE_LIMIT_ERROR' || raw . includes ( '429' ) || raw . includes ( 'quota' ) ) {
1091+ return 'Rate limit or quota exceeded. Wait a moment or check your Google Cloud billing.' ;
1092+ }
1093+ if ( type === 'TIMEOUT_ERROR' ) {
1094+ return 'Request timed out. The Google API may be slow or unreachable right now.' ;
1095+ }
1096+ if ( type === 'MODEL_ERROR' || raw . includes ( 'model' ) || raw . includes ( '404' ) ) {
1097+ return 'The configured Gemini model is unavailable. Try a different model in Settings.' ;
1098+ }
1099+ // Fall back to a stripped-down raw message (no SDK prefix noise)
1100+ return ( error ?. message || 'Connection failed' ) . replace ( / ^ \[ G o o g l e G e n e r a t i v e A I E r r o r \] : \s * / i, '' ) ;
1101+ }
1102+
10711103 updateApiKey ( newApiKey ) {
10721104 process . env . GEMINI_API_KEY = newApiKey ;
10731105 this . isInitialized = false ;
0 commit comments