@@ -2306,17 +2306,86 @@ export const validateAndPrepareUploadFile = (appPath: string) => {
23062306} ;
23072307
23082308export const handleUploadError = ( uploadError : any , spinner : any ) => {
2309- if ( uploadError . response ?. data ?. message ?. includes ( 'The file is too large' ) ) {
2310- spinner . fail ( `File size exceeds the maximum allowed limit of 3 GB.` ) ;
2311- throw new AppcircleExitError ( 'File size exceeds the maximum allowed limit of 3 GB.' , 1 ) ;
2312- } else if ( uploadError instanceof ProgramError ) {
2313- spinner . fail ( uploadError . message ) ;
2309+ // Get error messages from different sources
2310+ // API can return error as response.data.message (object) or response.data (string)
2311+ const responseData = uploadError . response ?. data ;
2312+ const apiMessage = typeof responseData === 'string' ? responseData : ( responseData ?. message || '' ) ;
2313+ const axiosMessage = uploadError . message || '' ;
2314+ const statusCode = uploadError . response ?. status ;
2315+
2316+ // Check for file size errors first
2317+ if ( apiMessage . includes ( 'The file is too large' ) || axiosMessage . includes ( 'The file is too large' ) ) {
2318+ if ( spinner && typeof spinner . stop === 'function' ) {
2319+ spinner . stop ( ) ;
2320+ }
2321+ const errorMessage = 'File size exceeds the maximum allowed limit of 3 GB.' ;
2322+ console . error ( errorMessage + '\n' ) ;
2323+ if ( spinner && typeof spinner . fail === 'function' ) {
2324+ spinner . fail ( errorMessage ) ;
2325+ }
2326+ throw new AppcircleExitError ( '' , 1 ) ;
2327+ }
2328+
2329+ // Check for ProgramError
2330+ if ( uploadError instanceof ProgramError ) {
2331+ if ( spinner && typeof spinner . fail === 'function' ) {
2332+ spinner . fail ( uploadError . message ) ;
2333+ }
23142334 throw new AppcircleExitError ( uploadError . message , 1 ) ;
2315- } else if ( uploadError . message && uploadError . message . includes ( 'Cannot read properties' ) ) {
2316- spinner . fail ( `API response format error. Please check your connection settings (AUTH_HOSTNAME and API_HOSTNAME).` ) ;
2317- throw new AppcircleExitError ( 'API response format error. Please check your connection settings (AUTH_HOSTNAME and API_HOSTNAME).' , 1 ) ;
23182335 }
2319- spinner . fail ( `Upload failed: ${ uploadError . message || 'Unknown error' } ` ) ;
2336+
2337+ // Check for API response format errors
2338+ if ( uploadError . message && uploadError . message . includes ( 'Cannot read properties' ) ) {
2339+ if ( spinner && typeof spinner . stop === 'function' ) {
2340+ spinner . stop ( ) ;
2341+ }
2342+ const errorMessage = 'API response format error. Please check your connection settings (AUTH_HOSTNAME and API_HOSTNAME).' ;
2343+ console . error ( errorMessage + '\n' ) ;
2344+ if ( spinner && typeof spinner . fail === 'function' ) {
2345+ spinner . fail ( errorMessage ) ;
2346+ }
2347+ throw new AppcircleExitError ( '' , 1 ) ;
2348+ }
2349+
2350+ // Handle file extension errors with better messaging
2351+ // Check both API message and axios message (which may contain the API message concatenated)
2352+ const combinedMessage = ( apiMessage + ' ' + axiosMessage ) . toLowerCase ( ) ;
2353+ const isFileExtensionError =
2354+ combinedMessage . includes ( 'extension' ) ||
2355+ combinedMessage . includes ( 'file extension' ) ||
2356+ combinedMessage . includes ( 'not match file extension' ) ||
2357+ combinedMessage . includes ( 'match file extension' ) ||
2358+ combinedMessage . includes ( 'extension is' ) ||
2359+ / e x t e n s i o n \s + i s \s + \. \w + / . test ( combinedMessage ) ||
2360+ / n o t \s + m a t c h \s + f i l e \s + e x t e n s i o n / i. test ( combinedMessage ) ||
2361+ // Also check if axios message contains "Bad Request" followed by extension-related text
2362+ ( axiosMessage && / b a d \s + r e q u e s t .* e x t e n s i o n / i. test ( axiosMessage . toLowerCase ( ) ) ) ;
2363+
2364+ if ( isFileExtensionError ) {
2365+ if ( spinner && typeof spinner . stop === 'function' ) {
2366+ spinner . stop ( ) ;
2367+ }
2368+ console . error ( 'Invalid file type. Extension should be .ipa, .apk, or .aab.\n' ) ;
2369+ if ( spinner && typeof spinner . fail === 'function' ) {
2370+ spinner . fail ( 'Request failed with status code 400 Bad Request.' ) ;
2371+ }
2372+ throw new AppcircleExitError ( '' , 1 ) ;
2373+ }
2374+
2375+ // For other errors with status code
2376+ if ( statusCode ) {
2377+ if ( spinner && typeof spinner . fail === 'function' ) {
2378+ spinner . fail ( `Request failed with status code ${ statusCode } ${ uploadError . response ?. statusText || 'Bad Request' } .` ) ;
2379+ }
2380+ if ( apiMessage && apiMessage . trim ( ) ) {
2381+ console . error ( '\n' + apiMessage ) ;
2382+ }
2383+ throw new AppcircleExitError ( apiMessage || axiosMessage || 'Upload failed' , 1 ) ;
2384+ }
2385+
2386+ if ( spinner && typeof spinner . fail === 'function' ) {
2387+ spinner . fail ( `Upload failed: ${ uploadError . message || 'Unknown error' } ` ) ;
2388+ }
23202389 throw uploadError ;
23212390} ;
23222391
@@ -2486,13 +2555,13 @@ export const handleDistributionUpload = async (command: ProgramCommand, params:
24862555
24872556 const { expandedPath, fileName, stats } = validateAndPrepareUploadFile ( params . app ) ;
24882557
2489- const uploadResponse = await getTestingDistributionUploadInformation ( {
2490- fileName,
2491- fileSize : stats . size ,
2492- distProfileId : params . distProfileId ,
2493- } ) ;
2494-
24952558 try {
2559+ const uploadResponse = await getTestingDistributionUploadInformation ( {
2560+ fileName,
2561+ fileSize : stats . size ,
2562+ distProfileId : params . distProfileId ,
2563+ } ) ;
2564+
24962565 await uploadArtifactWithSignedUrl ( { app : expandedPath , uploadInfo : uploadResponse } ) ;
24972566 const commitFileResponse = await commitTestingDistributionFileUpload ( {
24982567 fileId : uploadResponse . fileId ,
@@ -3715,14 +3784,68 @@ export const handleReleaseCandidateMarking = async (params: any, shouldMarkAsRel
37153784 }
37163785} ;
37173786
3718- export const handlePublishUploadError = ( uploadError : any ) : never => {
3719- if ( uploadError . response ?. data ?. message ?. includes ( 'The file is too large' ) ) {
3720- throw new AppcircleExitError ( 'File size exceeds the maximum allowed limit of 3 GB.' , 1 ) ;
3721- } else if ( uploadError instanceof ProgramError ) {
3787+ export const handlePublishUploadError = ( uploadError : any , spinner ?: any ) : never => {
3788+ // Get error messages from different sources
3789+ // API can return error as response.data.message (object) or response.data (string)
3790+ const responseData = uploadError . response ?. data ;
3791+ const apiMessage = typeof responseData === 'string' ? responseData : ( responseData ?. message || '' ) ;
3792+ const axiosMessage = uploadError . message || '' ;
3793+ const statusCode = uploadError . response ?. status ;
3794+
3795+ // Check for file size errors
3796+ if ( apiMessage . includes ( 'The file is too large' ) || axiosMessage . includes ( 'The file is too large' ) ) {
3797+ const errorMessage = 'File size exceeds the maximum allowed limit of 3 GB.' ;
3798+ if ( spinner ) {
3799+ spinner . stop ( ) ;
3800+ }
3801+ console . error ( errorMessage + '\n' ) ;
3802+ if ( spinner ) {
3803+ spinner . fail ( `Request failed with status code ${ statusCode || 400 } Bad Request.` ) ;
3804+ }
3805+ throw new AppcircleExitError ( errorMessage , 1 ) ;
3806+ }
3807+
3808+ // Check for ProgramError
3809+ if ( uploadError instanceof ProgramError ) {
37223810 throw new AppcircleExitError ( uploadError . message , 1 ) ;
3723- } else if ( uploadError . message && uploadError . message . includes ( 'Cannot read properties' ) ) {
3724- throw new AppcircleExitError ( 'API response format error. Please check your connection settings (AUTH_HOSTNAME and API_HOSTNAME).' , 1 ) ;
37253811 }
3812+
3813+ // Check for API response format errors
3814+ if ( uploadError . message && uploadError . message . includes ( 'Cannot read properties' ) ) {
3815+ const errorMessage = 'API response format error' ;
3816+ if ( spinner ) {
3817+ spinner . stop ( ) ;
3818+ }
3819+ console . error ( errorMessage + '. Please check your connection settings (AUTH_HOSTNAME and API_HOSTNAME).\n' ) ;
3820+ if ( spinner ) {
3821+ spinner . fail ( `Request failed with status code ${ statusCode || 500 } ${ uploadError . response ?. statusText || 'Internal Server Error' } .` ) ;
3822+ }
3823+ throw new AppcircleExitError ( errorMessage , 1 ) ;
3824+ }
3825+
3826+ // Handle file extension errors with better messaging
3827+ const combinedMessage = ( apiMessage + ' ' + axiosMessage ) . toLowerCase ( ) ;
3828+ const isFileExtensionError =
3829+ combinedMessage . includes ( 'extension' ) ||
3830+ combinedMessage . includes ( 'file extension' ) ||
3831+ combinedMessage . includes ( 'not match file extension' ) ||
3832+ combinedMessage . includes ( 'match file extension' ) ||
3833+ combinedMessage . includes ( 'extension is' ) ||
3834+ / e x t e n s i o n \s + i s \s + \. \w + / . test ( combinedMessage ) ||
3835+ / n o t \s + m a t c h \s + f i l e \s + e x t e n s i o n / i. test ( combinedMessage ) ||
3836+ ( axiosMessage && / b a d \s + r e q u e s t .* e x t e n s i o n / i. test ( axiosMessage . toLowerCase ( ) ) ) ;
3837+
3838+ if ( isFileExtensionError ) {
3839+ if ( spinner ) {
3840+ spinner . stop ( ) ;
3841+ }
3842+ console . error ( 'Invalid file type. Extension should be .ipa, .apk, or .aab.\n' ) ;
3843+ if ( spinner ) {
3844+ spinner . fail ( 'Request failed with status code 400 Bad Request.' ) ;
3845+ }
3846+ throw new AppcircleExitError ( '' , 1 ) ;
3847+ }
3848+
37263849 throw uploadError ; // Re-throw to be caught by the outer catch
37273850} ;
37283851
0 commit comments