@@ -48,7 +48,6 @@ use serde::{Deserialize, Serialize};
4848use std:: {
4949 collections:: HashMap ,
5050 fmt:: { self , Debug , Display } ,
51- fs:: create_dir_all,
5251 future:: ready,
5352 num:: { NonZeroU16 , NonZeroU64 } ,
5453 ops:: Range ,
@@ -264,15 +263,12 @@ impl ObjectStorage {
264263 /// client is not serializeable and must be initialized after deserialization. Under normal construction
265264 /// the original client is returned immediately.
266265 #[ instrument( skip_all) ]
267- async fn get_client ( & self , settings : & Settings ) -> & Arc < dyn ObjectStore > {
266+ async fn get_client (
267+ & self ,
268+ settings : & Settings ,
269+ ) -> StorageResult < & Arc < dyn ObjectStore > > {
268270 self . client
269- . get_or_init ( || async {
270- // TODO: handle error better?
271- #[ expect( clippy:: expect_used) ]
272- self . backend
273- . mk_object_store ( settings)
274- . expect ( "failed to create object store" )
275- } )
271+ . get_or_try_init ( || async { self . backend . mk_object_store ( settings) } )
276272 . await
277273 }
278274
@@ -287,7 +283,7 @@ impl ObjectStorage {
287283 /// Intended for testing and debugging purposes only.
288284 pub async fn all_keys ( & self ) -> StorageResult < Vec < String > > {
289285 self . get_client ( & self . backend . default_settings ( ) )
290- . await
286+ . await ?
291287 . list ( None )
292288 . map_ok ( |obj| obj. location . to_string ( ) )
293289 . try_collect ( )
@@ -362,6 +358,10 @@ impl Storage for ObjectStorage {
362358 Ok ( self . backend . can_write ( ) )
363359 }
364360
361+ async fn create_location_if_needed ( & self ) -> StorageResult < ( ) > {
362+ self . backend . create_location_if_needed ( )
363+ }
364+
365365 #[ instrument( skip_all) ]
366366 async fn default_settings ( & self ) -> StorageResult < Settings > {
367367 Ok ( self . backend . default_settings ( ) )
@@ -394,7 +394,7 @@ impl Storage for ObjectStorage {
394394 let options = PutOptions { mode, attributes, ..PutOptions :: default ( ) } ;
395395 // FIXME: use multipart
396396 let res =
397- self . get_client ( settings) . await . put_opts ( & path, bytes. into ( ) , options) . await ;
397+ self . get_client ( settings) . await ? . put_opts ( & path, bytes. into ( ) , options) . await ;
398398 match res {
399399 Ok ( res) => {
400400 let new_version = VersionInfo {
@@ -431,7 +431,7 @@ impl Storage for ObjectStorage {
431431 if_match : version. etag ( ) . map ( |e| strip_quotes ( e) . into ( ) ) ,
432432 ..Default :: default ( )
433433 } ;
434- let result = self . get_client ( settings) . await . get_opts ( & from, opts) . await ;
434+ let result = self . get_client ( settings) . await ? . get_opts ( & from, opts) . await ;
435435 match result {
436436 Ok ( result) => {
437437 let bytes = result
@@ -440,7 +440,7 @@ impl Storage for ObjectStorage {
440440 . map_err ( |e| StorageErrorKind :: ObjectStore ( Box :: new ( e) ) )
441441 . capture ( ) ?;
442442 self . get_client ( settings)
443- . await
443+ . await ?
444444 . put ( & to, bytes. into ( ) )
445445 . await
446446 . map_err ( |e| StorageErrorKind :: ObjectStore ( Box :: new ( e) ) )
@@ -454,7 +454,7 @@ impl Storage for ObjectStorage {
454454 Err ( err) => Err ( obj_store_error ( err) ) ,
455455 }
456456 } else {
457- match self . get_client ( settings) . await . copy ( & from, & to) . await {
457+ match self . get_client ( settings) . await ? . copy ( & from, & to) . await {
458458 Ok ( _) => {
459459 Ok ( VersionedUpdateResult :: Updated { new_version : version. clone ( ) } )
460460 }
@@ -472,7 +472,7 @@ impl Storage for ObjectStorage {
472472 ) -> StorageResult < BoxStream < ' a , StorageResult < ListInfo < String > > > > {
473473 let prefix = ObjectPath :: from ( format ! ( "{}/{}" , self . backend. prefix( ) , prefix) ) ;
474474 let stream =
475- self . get_client ( settings) . await . list ( Some ( & prefix) ) . map ( move |object| {
475+ self . get_client ( settings) . await ? . list ( Some ( & prefix) ) . map ( move |object| {
476476 let prefix = prefix. clone ( ) ;
477477 object
478478 . map_err ( obj_store_error)
@@ -496,7 +496,7 @@ impl Storage for ObjectStorage {
496496 sizes. insert ( path, size) ;
497497 }
498498 let results =
499- self . get_client ( settings) . await . delete_stream ( stream:: iter ( ids) . boxed ( ) ) ;
499+ self . get_client ( settings) . await ? . delete_stream ( stream:: iter ( ids) . boxed ( ) ) ;
500500 let res = results
501501 . fold ( DeleteObjectsResult :: default ( ) , |mut res, delete_result| {
502502 if let Ok ( deleted_path) = delete_result {
@@ -525,7 +525,7 @@ impl Storage for ObjectStorage {
525525 let path = self . prefixed_path ( path) ;
526526 let res = self
527527 . get_client ( settings)
528- . await
528+ . await ?
529529 . head ( & path)
530530 . await
531531 . map_err ( Box :: new)
@@ -598,7 +598,7 @@ impl ObjectStorage {
598598 . and_then ( |v| v. etag ( ) . map ( |e| strip_quotes ( e) . into ( ) ) ) ,
599599 ..Default :: default ( )
600600 } ;
601- let res = self . get_client ( settings) . await . get_opts ( & full_key, opts) . await ;
601+ let res = self . get_client ( settings) . await ? . get_opts ( & full_key, opts) . await ;
602602
603603 match res {
604604 Ok ( result) => {
@@ -640,6 +640,10 @@ pub trait ObjectStoreBackend: Debug + Display + Sync + Send {
640640 fn can_write ( & self ) -> bool {
641641 true
642642 }
643+
644+ fn create_location_if_needed ( & self ) -> Result < ( ) , StorageError > {
645+ Ok ( ( ) )
646+ }
643647}
644648
645649#[ derive( Debug , Serialize , Deserialize ) ]
@@ -717,8 +721,13 @@ impl ObjectStoreBackend for LocalFileSystemObjectStoreBackend {
717721 & self ,
718722 _settings : & Settings ,
719723 ) -> Result < Arc < dyn ObjectStore > , StorageError > {
720- create_dir_all ( & self . path ) . capture ( ) ?;
721- let path = std:: fs:: canonicalize ( & self . path ) . capture ( ) ?;
724+ let path = std:: fs:: canonicalize ( & self . path ) . map_err ( |err| {
725+ if err. kind ( ) == std:: io:: ErrorKind :: NotFound {
726+ StorageError :: capture ( StorageErrorKind :: ObjectNotFound )
727+ } else {
728+ StorageError :: capture ( StorageErrorKind :: IOError ( err) )
729+ }
730+ } ) ?;
722731 let fs = LocalFileSystem :: new_with_prefix ( path) . capture_box ( ) ?;
723732 Ok ( Arc :: new ( fs) )
724733 }
@@ -751,6 +760,11 @@ impl ObjectStoreBackend for LocalFileSystemObjectStoreBackend {
751760 ..Default :: default ( )
752761 }
753762 }
763+
764+ fn create_location_if_needed ( & self ) -> Result < ( ) , StorageError > {
765+ std:: fs:: create_dir_all ( & self . path ) . capture ( ) ?;
766+ Ok ( ( ) )
767+ }
754768}
755769
756770#[ cfg( feature = "http" ) ]
0 commit comments