@@ -149,7 +149,7 @@ pub async fn execute_upload(
149149 data : Vec < u8 > ,
150150 content_type : Option < String > ,
151151 metadata : Option < HashMap < String , String > > ,
152- ) -> Result < UploadResult , String > {
152+ ) -> Result < UploadResult , PyErr > {
153153 let start = Instant :: now ( ) ;
154154 let size = data. len ( ) ;
155155
@@ -196,7 +196,7 @@ async fn execute_simple_upload(
196196 data : Vec < u8 > ,
197197 content_type : Option < String > ,
198198 metadata : Option < HashMap < String , String > > ,
199- ) -> Result < S3Metadata , String > {
199+ ) -> Result < S3Metadata , PyErr > {
200200 let size = data. len ( ) as u64 ;
201201
202202 let mut req = client
@@ -215,10 +215,10 @@ async fn execute_simple_upload(
215215 }
216216 }
217217
218- let resp = req. send ( ) . await . map_err ( |e| {
219- let py_err = map_s3_error ( e , Some ( bucket ) , Some ( key ) ) ;
220- format ! ( "{}" , py_err )
221- } ) ?;
218+ let resp = req
219+ . send ( )
220+ . await
221+ . map_err ( |e| map_s3_error ( e , Some ( bucket ) , Some ( key ) ) ) ?;
222222
223223 Ok ( S3Metadata {
224224 bucket : bucket. to_string ( ) ,
@@ -239,7 +239,7 @@ async fn execute_multipart_upload(
239239 data : Vec < u8 > ,
240240 content_type : Option < String > ,
241241 metadata : Option < HashMap < String , String > > ,
242- ) -> Result < ( S3Metadata , u32 ) , String > {
242+ ) -> Result < ( S3Metadata , u32 ) , PyErr > {
243243 let size = data. len ( ) as u64 ;
244244
245245 let mut create_req = client. create_multipart_upload ( ) . bucket ( bucket) . key ( key) ;
@@ -254,14 +254,14 @@ async fn execute_multipart_upload(
254254 }
255255 }
256256
257- let create_resp = create_req. send ( ) . await . map_err ( |e| {
258- let py_err = map_s3_error ( e , Some ( bucket ) , Some ( key ) ) ;
259- format ! ( "{}" , py_err )
260- } ) ?;
257+ let create_resp = create_req
258+ . send ( )
259+ . await
260+ . map_err ( |e| map_s3_error ( e , Some ( bucket ) , Some ( key ) ) ) ?;
261261
262262 let upload_id = create_resp
263263 . upload_id ( )
264- . ok_or ( "No upload ID returned" ) ?
264+ . ok_or_else ( || S3Exception :: new_err ( "No upload ID returned" ) ) ?
265265 . to_string ( ) ;
266266
267267 let part_size = calculate_part_size ( data. len ( ) ) ;
@@ -299,8 +299,7 @@ async fn execute_multipart_upload(
299299 . upload_id ( & upload_id)
300300 . send ( )
301301 . await ;
302- let py_err = map_s3_error ( e, Some ( bucket) , Some ( key) ) ;
303- return Err ( format ! ( "Failed to upload part {}: {}" , part_number, py_err) ) ;
302+ return Err ( map_s3_error ( e, Some ( bucket) , Some ( key) ) ) ;
304303 }
305304 }
306305
@@ -319,10 +318,7 @@ async fn execute_multipart_upload(
319318 . multipart_upload ( completed)
320319 . send ( )
321320 . await
322- . map_err ( |e| {
323- let py_err = map_s3_error ( e, Some ( bucket) , Some ( key) ) ;
324- format ! ( "{}" , py_err)
325- } ) ?;
321+ . map_err ( |e| map_s3_error ( e, Some ( bucket) , Some ( key) ) ) ?;
326322
327323 api_calls += 1 ;
328324
@@ -349,7 +345,7 @@ pub async fn execute_download(
349345 client : Client ,
350346 bucket : String ,
351347 key : String ,
352- ) -> Result < DownloadResult , String > {
348+ ) -> Result < DownloadResult , PyErr > {
353349 let start = Instant :: now ( ) ;
354350
355351 let resp = client
@@ -358,16 +354,13 @@ pub async fn execute_download(
358354 . key ( & key)
359355 . send ( )
360356 . await
361- . map_err ( |e| {
362- let py_err = map_s3_error ( e, Some ( & bucket) , Some ( & key) ) ;
363- format ! ( "{}" , py_err)
364- } ) ?;
357+ . map_err ( |e| map_s3_error ( e, Some ( & bucket) , Some ( & key) ) ) ?;
365358
366359 let data = resp
367360 . body
368361 . collect ( )
369362 . await
370- . map_err ( |e| format ! ( "Failed to read S3 body: {}" , e) )
363+ . map_err ( |e| S3Exception :: new_err ( format ! ( "Failed to read S3 body: {}" , e) ) )
371364 . map ( |data| data. into_bytes ( ) . to_vec ( ) ) ?;
372365
373366 let duration_ms = start. elapsed ( ) . as_secs_f64 ( ) * 1000.0 ;
@@ -389,7 +382,7 @@ pub async fn execute_save_to_file(
389382 bucket : String ,
390383 key : String ,
391384 path : String ,
392- ) -> Result < SaveToFileResult , String > {
385+ ) -> Result < SaveToFileResult , PyErr > {
393386 use tokio:: io:: AsyncWriteExt ;
394387
395388 let start = Instant :: now ( ) ;
@@ -400,32 +393,29 @@ pub async fn execute_save_to_file(
400393 . key ( & key)
401394 . send ( )
402395 . await
403- . map_err ( |e| {
404- let py_err = map_s3_error ( e, Some ( & bucket) , Some ( & key) ) ;
405- format ! ( "{}" , py_err)
406- } ) ?;
396+ . map_err ( |e| map_s3_error ( e, Some ( & bucket) , Some ( & key) ) ) ?;
407397
408398 let mut file = tokio:: fs:: File :: create ( & path)
409399 . await
410- . map_err ( |e| format ! ( "Failed to create file: {}" , e) ) ?;
400+ . map_err ( |e| S3Exception :: new_err ( format ! ( "Failed to create file: {}" , e) ) ) ?;
411401
412402 let mut stream = resp. body ;
413403 let mut total_bytes: u64 = 0 ;
414404
415405 while let Some ( chunk) = stream
416406 . try_next ( )
417407 . await
418- . map_err ( |e| format ! ( "Failed to read chunk: {}" , e) ) ?
408+ . map_err ( |e| S3Exception :: new_err ( format ! ( "Failed to read chunk: {}" , e) ) ) ?
419409 {
420410 total_bytes += chunk. len ( ) as u64 ;
421411 file. write_all ( & chunk)
422412 . await
423- . map_err ( |e| format ! ( "Failed to write to file: {}" , e) ) ?;
413+ . map_err ( |e| S3Exception :: new_err ( format ! ( "Failed to write to file: {}" , e) ) ) ?;
424414 }
425415
426416 file. flush ( )
427417 . await
428- . map_err ( |e| format ! ( "Failed to flush file: {}" , e) ) ?;
418+ . map_err ( |e| S3Exception :: new_err ( format ! ( "Failed to flush file: {}" , e) ) ) ?;
429419
430420 let duration_ms = start. elapsed ( ) . as_secs_f64 ( ) * 1000.0 ;
431421
@@ -445,19 +435,19 @@ pub async fn execute_presigned_url(
445435 bucket : String ,
446436 key : String ,
447437 expires_secs : u64 ,
448- ) -> Result < PresignedUrlResult , String > {
438+ ) -> Result < PresignedUrlResult , PyErr > {
449439 let start = Instant :: now ( ) ;
450440
451441 let presign_config = PresigningConfig :: expires_in ( Duration :: from_secs ( expires_secs) )
452- . map_err ( |e| format ! ( "Invalid expiration: {}" , e) ) ?;
442+ . map_err ( |e| S3Exception :: new_err ( format ! ( "Invalid expiration: {}" , e) ) ) ?;
453443
454444 let presigned = client
455445 . get_object ( )
456446 . bucket ( & bucket)
457447 . key ( & key)
458448 . presigned ( presign_config)
459449 . await
460- . map_err ( |e| format ! ( "Failed to generate presigned URL: {}" , e) ) ?;
450+ . map_err ( |e| S3Exception :: new_err ( format ! ( "Failed to generate presigned URL: {}" , e) ) ) ?;
461451
462452 let duration_ms = start. elapsed ( ) . as_secs_f64 ( ) * 1000.0 ;
463453
@@ -476,7 +466,7 @@ pub async fn execute_delete(
476466 client : Client ,
477467 bucket : String ,
478468 key : String ,
479- ) -> Result < DeleteResult , String > {
469+ ) -> Result < DeleteResult , PyErr > {
480470 let start = Instant :: now ( ) ;
481471
482472 client
@@ -485,10 +475,7 @@ pub async fn execute_delete(
485475 . key ( & key)
486476 . send ( )
487477 . await
488- . map_err ( |e| {
489- let py_err = map_s3_error ( e, Some ( & bucket) , Some ( & key) ) ;
490- format ! ( "{}" , py_err)
491- } ) ?;
478+ . map_err ( |e| map_s3_error ( e, Some ( & bucket) , Some ( & key) ) ) ?;
492479
493480 let duration_ms = start. elapsed ( ) . as_secs_f64 ( ) * 1000.0 ;
494481
@@ -506,7 +493,7 @@ pub async fn execute_head(
506493 client : Client ,
507494 bucket : String ,
508495 key : String ,
509- ) -> Result < HeadResult , String > {
496+ ) -> Result < HeadResult , PyErr > {
510497 let start = Instant :: now ( ) ;
511498
512499 let resp = client
@@ -515,10 +502,7 @@ pub async fn execute_head(
515502 . key ( & key)
516503 . send ( )
517504 . await
518- . map_err ( |e| {
519- let py_err = map_s3_error ( e, Some ( & bucket) , Some ( & key) ) ;
520- format ! ( "{}" , py_err)
521- } ) ?;
505+ . map_err ( |e| map_s3_error ( e, Some ( & bucket) , Some ( & key) ) ) ?;
522506
523507 let duration_ms = start. elapsed ( ) . as_secs_f64 ( ) * 1000.0 ;
524508
@@ -580,9 +564,7 @@ pub fn upload_bytes<'py>(
580564 let data_vec = data. as_bytes ( ) . to_vec ( ) ;
581565
582566 pyo3_async_runtimes:: tokio:: future_into_py ( py, async move {
583- let result = execute_upload ( client, bucket, key, data_vec, content_type, metadata)
584- . await
585- . map_err ( S3Exception :: new_err) ?;
567+ let result = execute_upload ( client, bucket, key, data_vec, content_type, metadata) . await ?;
586568 Ok ( ( result. metadata , result. metrics ) )
587569 } )
588570}
@@ -595,9 +577,7 @@ pub fn download_bytes(
595577 key : String ,
596578) -> PyResult < Bound < ' _ , PyAny > > {
597579 pyo3_async_runtimes:: tokio:: future_into_py ( py, async move {
598- let result = execute_download ( client, bucket, key)
599- . await
600- . map_err ( S3Exception :: new_err) ?;
580+ let result = execute_download ( client, bucket, key) . await ?;
601581 Python :: attach ( |py| {
602582 let bytes = PyBytes :: new ( py, & result. data ) ;
603583 Ok ( ( bytes. unbind ( ) , result. metrics ) )
@@ -614,9 +594,7 @@ pub fn presigned_url(
614594 expires_secs : u64 ,
615595) -> PyResult < Bound < ' _ , PyAny > > {
616596 pyo3_async_runtimes:: tokio:: future_into_py ( py, async move {
617- let result = execute_presigned_url ( client, bucket, key, expires_secs)
618- . await
619- . map_err ( S3Exception :: new_err) ?;
597+ let result = execute_presigned_url ( client, bucket, key, expires_secs) . await ?;
620598 Ok ( ( result. url , result. metrics ) )
621599 } )
622600}
@@ -629,9 +607,7 @@ pub fn delete_object(
629607 key : String ,
630608) -> PyResult < Bound < ' _ , PyAny > > {
631609 pyo3_async_runtimes:: tokio:: future_into_py ( py, async move {
632- let result = execute_delete ( client, bucket, key)
633- . await
634- . map_err ( S3Exception :: new_err) ?;
610+ let result = execute_delete ( client, bucket, key) . await ?;
635611 Ok ( result. metrics )
636612 } )
637613}
@@ -644,9 +620,7 @@ pub fn head_object(
644620 key : String ,
645621) -> PyResult < Bound < ' _ , PyAny > > {
646622 pyo3_async_runtimes:: tokio:: future_into_py ( py, async move {
647- let result = execute_head ( client, bucket, key)
648- . await
649- . map_err ( S3Exception :: new_err) ?;
623+ let result = execute_head ( client, bucket, key) . await ?;
650624 Ok ( ( result. metadata , result. metrics ) )
651625 } )
652626}
@@ -660,9 +634,7 @@ pub fn save_to_file(
660634 path : String ,
661635) -> PyResult < Bound < ' _ , PyAny > > {
662636 pyo3_async_runtimes:: tokio:: future_into_py ( py, async move {
663- let result = execute_save_to_file ( client, bucket, key, path)
664- . await
665- . map_err ( S3Exception :: new_err) ?;
637+ let result = execute_save_to_file ( client, bucket, key, path) . await ?;
666638 Ok ( ( result. bytes_written , result. metrics ) )
667639 } )
668640}
@@ -688,9 +660,8 @@ pub fn sync_upload_bytes(
688660
689661 py. detach ( || {
690662 runtime. block_on ( async {
691- let result = execute_upload ( client, bucket, key, data_vec, content_type, metadata)
692- . await
693- . map_err ( S3Exception :: new_err) ?;
663+ let result =
664+ execute_upload ( client, bucket, key, data_vec, content_type, metadata) . await ?;
694665 Ok ( ( result. metadata , result. metrics ) )
695666 } )
696667 } )
@@ -708,13 +679,8 @@ pub fn sync_download_bytes<'py>(
708679 let bucket = bucket. to_string ( ) ;
709680 let key = key. to_string ( ) ;
710681
711- let result = py. detach ( || {
712- runtime. block_on ( async {
713- execute_download ( client, bucket, key)
714- . await
715- . map_err ( S3Exception :: new_err)
716- } )
717- } ) ?;
682+ let result =
683+ py. detach ( || runtime. block_on ( async { execute_download ( client, bucket, key) . await } ) ) ?;
718684
719685 let bytes = PyBytes :: new ( py, & result. data ) ;
720686 Ok ( ( bytes, result. metrics ) )
@@ -735,9 +701,7 @@ pub fn sync_presigned_url(
735701
736702 py. detach ( || {
737703 runtime. block_on ( async {
738- let result = execute_presigned_url ( client, bucket, key, expires_secs)
739- . await
740- . map_err ( S3Exception :: new_err) ?;
704+ let result = execute_presigned_url ( client, bucket, key, expires_secs) . await ?;
741705 Ok ( ( result. url , result. metrics ) )
742706 } )
743707 } )
@@ -757,9 +721,7 @@ pub fn sync_delete_object(
757721
758722 py. detach ( || {
759723 runtime. block_on ( async {
760- let result = execute_delete ( client, bucket, key)
761- . await
762- . map_err ( S3Exception :: new_err) ?;
724+ let result = execute_delete ( client, bucket, key) . await ?;
763725 Ok ( result. metrics )
764726 } )
765727 } )
@@ -779,9 +741,7 @@ pub fn sync_head_object(
779741
780742 py. detach ( || {
781743 runtime. block_on ( async {
782- let result = execute_head ( client, bucket, key)
783- . await
784- . map_err ( S3Exception :: new_err) ?;
744+ let result = execute_head ( client, bucket, key) . await ?;
785745 Ok ( ( result. metadata , result. metrics ) )
786746 } )
787747 } )
@@ -803,9 +763,7 @@ pub fn sync_save_to_file(
803763
804764 py. detach ( || {
805765 runtime. block_on ( async {
806- let result = execute_save_to_file ( client, bucket, key, path)
807- . await
808- . map_err ( S3Exception :: new_err) ?;
766+ let result = execute_save_to_file ( client, bucket, key, path) . await ?;
809767 Ok ( ( result. bytes_written , result. metrics ) )
810768 } )
811769 } )
0 commit comments