11import { Command } from 'commander' ;
2+ import { FetchError } from 'ofetch' ;
23import { upgradeCvm , getCvmByAppId } from '@/src/api/cvms' ;
34import { logger } from '@/src/utils/logger' ;
45import fs from 'node:fs' ;
@@ -44,6 +45,7 @@ export const upgradeCommand = new Command()
4445
4546 // Update Docker Compose file if provided
4647 let composeString = '' ;
48+ let env_keys = [ ] ;
4749 if ( options . compose ) {
4850 try {
4951 composeString = fs . readFileSync ( options . compose , 'utf8' ) ;
@@ -74,6 +76,7 @@ export const upgradeCommand = new Command()
7476 try {
7577 envs = parseEnv ( [ ] , options . envFile ) ;
7678 encrypted_env = await encryptEnvVars ( envs , currentCvm . encrypted_env_pubkey ) ;
79+ env_keys = envs . map ( i => i . key )
7780 } catch ( error ) {
7881 logger . error ( `Failed to read environment file: ${ error instanceof Error ? error . message : String ( error ) } ` ) ;
7982 process . exit ( 1 ) ;
@@ -90,9 +93,11 @@ export const upgradeCommand = new Command()
9093 version : "1.0.0" ,
9194 features : [ "kms" , "tproxy-net" ] ,
9295 name : `app_${ resolvedAppId } ` ,
96+ allowed_envs : env_keys ,
9397 } ,
9498 encrypted_env,
9599 allow_restart : true ,
100+ env_keys : env_keys ,
96101 } ;
97102
98103 // Upgrade the CVM
@@ -116,6 +121,28 @@ export const upgradeCommand = new Command()
116121 ) ;
117122 } catch ( error ) {
118123 logger . error ( `Failed to upgrade CVM: ${ error instanceof Error ? error . message : String ( error ) } ` ) ;
124+
125+ // Multiple ways to check if it's a FetchError:
126+ // 1. instanceof check (standard but may fail due to module loading)
127+ // 2. Check constructor.name (works across module boundaries)
128+ // 3. Check for FetchError-specific properties (status, statusText, data, request)
129+ const isFetchError = error instanceof FetchError ||
130+ ( error as any ) ?. constructor ?. name === 'FetchError' ||
131+ ( error && typeof error === 'object' && 'status' in error && 'statusText' in error && 'data' in error ) ;
132+
133+ if ( isFetchError ) {
134+ const fetchError = error as FetchError ;
135+ logger . error ( '=== HTTP Error Details ===' ) ;
136+ logger . error ( 'Status:' , fetchError . status ) ;
137+ logger . error ( 'Status Text:' , fetchError . statusText ) ;
138+ logger . error ( 'URL:' , fetchError . request ) ;
139+ logger . error ( 'Response Body:' , JSON . stringify ( fetchError . data , null , 2 ) ) ;
140+ if ( options . debug ) {
141+ logger . error ( 'Full Error Object:' , error ) ;
142+ }
143+ } else if ( options . debug ) {
144+ logger . error ( 'Full Error:' , error ) ;
145+ }
119146 process . exit ( 1 ) ;
120147 }
121148 } ) ;
0 commit comments