Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 5 additions & 8 deletions handwritten/storage/src/transfer-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -963,23 +963,20 @@ export class TransferManager {
await Promise.all(promises);
return await mpuHelper.completeUpload();
} catch (e) {
let uploadMsg = (e as Error)?.message ?? String(e);
if (
(options.autoAbortFailure === undefined || options.autoAbortFailure) &&
mpuHelper.uploadId
) {
try {
await mpuHelper.abortUpload();
return;
Comment thread
thiyaguk09 marked this conversation as resolved.
} catch (e) {
throw new MultiPartUploadError(
(e as Error).message,
mpuHelper.uploadId!,
mpuHelper.partsMap!
);
} catch (abortErr) {
const abortMsg = (abortErr as Error)?.message ?? String(abortErr);
uploadMsg += `\n${abortMsg}`;
}
}
throw new MultiPartUploadError(
(e as Error).message,
uploadMsg,
mpuHelper.uploadId!,
mpuHelper.partsMap!
);
Expand Down
89 changes: 82 additions & 7 deletions handwritten/storage/test/transfer-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -847,13 +847,14 @@ describe('Transfer Manager', () => {
);
});

it('should call abortUpload when a failure occurs after an uploadID is established', async () => {
it('should call abortUpload and reject with the original error when a failure occurs after an uploadID is established', async () => {
const fakeId = '123';
const fakePartsMap = new Map<number, string>([[1, 'etag-1']]);
const expectedErr = new MultiPartUploadError(
'Hello World',
'',
new Map<number, string>()
fakeId,
fakePartsMap
);
const fakeId = '123';

mockGeneratorFunction = (bucket, fileName, uploadId, partsMap) => {
fakeHelper = sandbox.createStubInstance(FakeXMLHelper);
Expand All @@ -862,7 +863,8 @@ describe('Transfer Manager', () => {
fakeHelper.initiateUpload.resolves();
fakeHelper.uploadPart.callsFake(() => {
fakeHelper.uploadId = fakeId;
return Promise.reject(expectedErr);
fakeHelper.partsMap = fakePartsMap;
return Promise.reject(new Error(expectedErr.message));
});
fakeHelper.completeUpload.resolves();
fakeHelper.abortUpload.callsFake(() => {
Expand All @@ -872,9 +874,82 @@ describe('Transfer Manager', () => {
return fakeHelper;
};

assert.doesNotThrow(() =>
transferManager.uploadFileInChunks(filePath, {}, mockGeneratorFunction)
await assert.rejects(
Comment thread
thiyaguk09 marked this conversation as resolved.
transferManager.uploadFileInChunks(filePath, {}, mockGeneratorFunction),
expectedErr
);
assert.strictEqual(fakeHelper.abortUpload.calledOnce, true);
});

it('should not call abortUpload when autoAbortFailure is false and a failure occurs after an uploadID is established', async () => {
const fakeId = '123';
const fakePartsMap = new Map<number, string>([[1, 'etag-1']]);
const expectedErr = new MultiPartUploadError(
'Hello World',
fakeId,
fakePartsMap
);

mockGeneratorFunction = (bucket, fileName, uploadId, partsMap) => {
fakeHelper = sandbox.createStubInstance(FakeXMLHelper);
fakeHelper.uploadId = uploadId || '';
fakeHelper.partsMap = partsMap || new Map<number, string>();
fakeHelper.initiateUpload.resolves();
fakeHelper.uploadPart.callsFake(() => {
fakeHelper.uploadId = fakeId;
fakeHelper.partsMap = fakePartsMap;
return Promise.reject(new Error(expectedErr.message));
});
fakeHelper.completeUpload.resolves();
fakeHelper.abortUpload.resolves();
return fakeHelper;
};

await assert.rejects(
transferManager.uploadFileInChunks(
filePath,
{autoAbortFailure: false},
mockGeneratorFunction
),
expectedErr
);
assert.strictEqual(fakeHelper.abortUpload.notCalled, true);
});

it('should reject with an error containing both messages when both uploadPart and abortUpload fail', async () => {
const fakeId = '123';
const fakePartsMap = new Map<number, string>([[1, 'etag-1']]);
const uploadErr = new Error('Chunk upload failed');
const abortErr = new Error('Abort upload failed');
const expectedErr = new MultiPartUploadError(
`${uploadErr.message}\n${abortErr.message}`,
fakeId,
fakePartsMap
);

mockGeneratorFunction = (bucket, fileName, uploadId, partsMap) => {
fakeHelper = sandbox.createStubInstance(FakeXMLHelper);
fakeHelper.uploadId = uploadId || '';
fakeHelper.partsMap = partsMap || new Map<number, string>();
fakeHelper.initiateUpload.resolves();
fakeHelper.uploadPart.callsFake(() => {
fakeHelper.uploadId = fakeId;
fakeHelper.partsMap = fakePartsMap;
return Promise.reject(uploadErr);
});
fakeHelper.completeUpload.resolves();
fakeHelper.abortUpload.callsFake(() => {
assert.strictEqual(fakeHelper.uploadId, fakeId);
return Promise.reject(abortErr);
});
return fakeHelper;
};

await assert.rejects(
transferManager.uploadFileInChunks(filePath, {}, mockGeneratorFunction),
expectedErr
Comment thread
thiyaguk09 marked this conversation as resolved.
);
assert.strictEqual(fakeHelper.abortUpload.calledOnce, true);
});

it('should set the appropriate `GCCL_GCS_CMD_KEY`', async () => {
Expand Down
Loading