diff --git a/packages/aws-amplify/package.json b/packages/aws-amplify/package.json index 159c7da99d5..c399a5309e6 100644 --- a/packages/aws-amplify/package.json +++ b/packages/aws-amplify/package.json @@ -515,7 +515,7 @@ "name": "[Storage] uploadData (S3)", "path": "./dist/esm/storage/index.mjs", "import": "{ uploadData }", - "limit": "22.95 kB" + "limit": "23.00 kB" } ] } diff --git a/packages/storage/__tests__/providers/s3/utils/client/s3Data/completeMultipartUpload.test.ts b/packages/storage/__tests__/providers/s3/utils/client/s3Data/completeMultipartUpload.test.ts index 5036a9de6fb..16e65d11b21 100644 --- a/packages/storage/__tests__/providers/s3/utils/client/s3Data/completeMultipartUpload.test.ts +++ b/packages/storage/__tests__/providers/s3/utils/client/s3Data/completeMultipartUpload.test.ts @@ -83,7 +83,6 @@ describe('completeMultipartUploadSerializer', () => { ], }, }); - console.log(output); expect(output).toEqual({ $metadata: expect.objectContaining(expectedMetadata), }); @@ -140,4 +139,18 @@ describe('completeMultipartUploadSerializer', () => { }), ).rejects.toThrow(integrityError); }); + + it('should fail with specific error messaging when ETag is missing from response', () => { + mockS3TransferHandler.mockResolvedValue( + mockBinaryResponse(completeMultipartUploadSuccessResponse), + ); + expect( + completeMultipartUpload(defaultConfig, { + Bucket: 'bucket', + Key: 'key', + UploadId: 'uploadId', + MultipartUpload: { Parts: [{ PartNumber: 1 }] }, + }), + ).rejects.toThrow('ETag missing'); + }); }); diff --git a/packages/storage/src/providers/s3/utils/client/s3data/completeMultipartUpload.ts b/packages/storage/src/providers/s3/utils/client/s3data/completeMultipartUpload.ts index e7c4c516157..6ce44756b76 100644 --- a/packages/storage/src/providers/s3/utils/client/s3data/completeMultipartUpload.ts +++ b/packages/storage/src/providers/s3/utils/client/s3data/completeMultipartUpload.ts @@ -36,7 +36,11 @@ import type { } from './types'; const INVALID_PARAMETER_ERROR_MSG = - 'Invalid parameter for ComplteMultipartUpload API'; + 'Invalid parameter for CompleteMultipartUpload API'; + +const MISSING_ETAG_ERROR_MSG = 'ETag missing from multipart upload'; +const MISSING_ETAG_ERROR_SUGGESTION = + 'Please ensure S3 bucket CORS configuration includes ETag as part of its `ExposeHeaders` element'; export type CompleteMultipartUploadInput = Pick< CompleteMultipartUploadCommandInput, @@ -95,7 +99,7 @@ const serializeCompletedMultipartUpload = ( input: CompletedMultipartUpload, ): string => { if (!input.Parts?.length) { - throw new Error(`${INVALID_PARAMETER_ERROR_MSG}: ${input}`); + throw new Error(`${INVALID_PARAMETER_ERROR_MSG}: ${JSON.stringify(input)}`); } return `${input.Parts.map( @@ -104,8 +108,13 @@ const serializeCompletedMultipartUpload = ( }; const serializeCompletedPartList = (input: CompletedPart): string => { - if (!input.ETag || input.PartNumber == null) { - throw new Error(`${INVALID_PARAMETER_ERROR_MSG}: ${input}`); + if (input.PartNumber == null) { + throw new Error(`${INVALID_PARAMETER_ERROR_MSG}: ${JSON.stringify(input)}`); + } + if (!input.ETag) { + throw new Error( + `${MISSING_ETAG_ERROR_MSG}: ${JSON.stringify(input)}. ${MISSING_ETAG_ERROR_SUGGESTION}`, + ); } const eTag = `${input.ETag}`;