diff --git a/minio/api.py b/minio/api.py index 8aba5f3f4..27cc5f6da 100644 --- a/minio/api.py +++ b/minio/api.py @@ -1527,7 +1527,15 @@ def _stream_put_object(self, bucket_name, object_name, parts_to_upload.append((bucket_name, object_name, upload_id, part_number, part_data)) # Run parts upload in parallel - pool.parallel_run(self._upload_part_routine, parts_to_upload) + try: + pool.parallel_run(self._upload_part_routine, parts_to_upload) + except: + # Any exception that occurs sends an abort on the + # on-going multipart operation. + self._remove_incomplete_upload(bucket_name, + object_name, + upload_id) + raise # Update uploaded_parts with the part uploads result # and check total uploaded data. @@ -1546,14 +1554,28 @@ def _stream_put_object(self, bucket_name, object_name, if total_uploaded != content_size: msg = 'Data uploaded {0} is not equal input size ' \ '{1}'.format(total_uploaded, content_size) + # cleanup incomplete upload upon incorrect upload + # automatically + self._remove_incomplete_upload(bucket_name, + object_name, + upload_id) raise InvalidSizeError(msg) # Complete all multipart transactions if possible. - mpart_result = self._complete_multipart_upload(bucket_name, - object_name, - upload_id, - uploaded_parts, - metadata=metadata) + try: + mpart_result = self._complete_multipart_upload(bucket_name, + object_name, + upload_id, + uploaded_parts, + metadata=metadata) + except: + # Any exception that occurs sends an abort on the + # on-going multipart operation. + self._remove_incomplete_upload(bucket_name, + object_name, + upload_id) + raise + # Return etag here. return mpart_result.etag