@@ -7,7 +7,7 @@ use anyhow::Result;
7
7
use async_once_cell:: OnceCell ;
8
8
use async_stream:: try_stream;
9
9
use chrono:: { DateTime , Utc } ;
10
- use futures:: { future, AsyncRead , Stream , StreamExt } ;
10
+ use futures:: { future, AsyncRead , Stream , StreamExt , TryStreamExt } ;
11
11
use libipld:: { Cid , IpldCodec } ;
12
12
use rand_core:: RngCore ;
13
13
use semver:: Version ;
@@ -429,11 +429,11 @@ impl PrivateFile {
429
429
) -> Result < Vec < u8 > > {
430
430
let mut content = Vec :: with_capacity ( self . get_content_size_upper_bound ( ) ) ;
431
431
self . stream_content ( 0 , forest, store)
432
- . for_each ( |chunk| {
433
- content. extend_from_slice ( & chunk. unwrap ( ) ) ;
434
- future:: ready ( ( ) )
432
+ . try_for_each ( |chunk| {
433
+ content. extend_from_slice ( & chunk) ;
434
+ future:: ready ( Ok ( ( ) ) )
435
435
} )
436
- . await ;
436
+ . await ? ;
437
437
Ok ( content)
438
438
}
439
439
@@ -941,12 +941,13 @@ mod tests {
941
941
mod proptests {
942
942
use super :: MAX_BLOCK_CONTENT_SIZE ;
943
943
use crate :: private:: { PrivateFile , PrivateForest } ;
944
+ use async_std:: io:: Cursor ;
944
945
use chrono:: Utc ;
945
946
use futures:: { future, StreamExt } ;
946
947
use proptest:: test_runner:: { RngAlgorithm , TestRng } ;
947
948
use std:: rc:: Rc ;
948
949
use test_strategy:: proptest;
949
- use wnfs_common:: MemoryBlockStore ;
950
+ use wnfs_common:: { BlockStoreError , MemoryBlockStore } ;
950
951
use wnfs_namefilter:: Namefilter ;
951
952
952
953
/// Size of the test file at "./test/fixtures/Clara Schumann, Scherzo no. 2, Op. 14.mp3"
@@ -1012,6 +1013,38 @@ mod proptests {
1012
1013
} )
1013
1014
}
1014
1015
1016
+ #[ proptest( cases = 100 ) ]
1017
+ fn can_propagate_missing_chunk_error (
1018
+ #[ strategy( 0 ..( MAX_BLOCK_CONTENT_SIZE * 2 ) ) ] length : usize ,
1019
+ ) {
1020
+ async_std:: task:: block_on ( async {
1021
+ let store = & mut MemoryBlockStore :: default ( ) ;
1022
+ let rng = & mut TestRng :: deterministic_rng ( RngAlgorithm :: ChaCha ) ;
1023
+ let forest = & mut Rc :: new ( PrivateForest :: new ( ) ) ;
1024
+
1025
+ let mut file = PrivateFile :: new ( Namefilter :: new ( ) , Utc :: now ( ) , rng) ;
1026
+
1027
+ file. set_content (
1028
+ Utc :: now ( ) ,
1029
+ & mut Cursor :: new ( vec ! [ 5u8 ; length] ) ,
1030
+ forest,
1031
+ & mut MemoryBlockStore :: default ( ) ,
1032
+ rng,
1033
+ )
1034
+ . await
1035
+ . unwrap ( ) ;
1036
+
1037
+ let error = file
1038
+ . get_content ( forest, store)
1039
+ . await
1040
+ . expect_err ( "Expected error" ) ;
1041
+
1042
+ let error = error. downcast_ref :: < BlockStoreError > ( ) . unwrap ( ) ;
1043
+
1044
+ assert ! ( matches!( error, BlockStoreError :: CIDNotFound ( _) ) ) ;
1045
+ } )
1046
+ }
1047
+
1015
1048
#[ proptest( cases = 10 ) ]
1016
1049
fn can_read_section_of_file (
1017
1050
#[ strategy( 0 ..FIXTURE_SCHERZO_SIZE ) ] size : usize ,
0 commit comments