@@ -152,18 +152,27 @@ impl core::fmt::Debug for JsStorage {
152152}
153153
154154/// Parse a JS array of digests.
155- fn parse_digest_array < T : Encode + Decode > ( js_value : & JsValue ) -> Set < Digest < T > > {
155+ ///
156+ /// Returns an error if any element cannot be cast to a `Digest`.
157+ fn parse_digest_array < T : Encode + Decode > (
158+ js_value : & JsValue ,
159+ ) -> Result < Set < Digest < T > > , JsStorageError > {
156160 let array = js_sys:: Array :: from ( js_value) ;
157161 let mut result = Set :: new ( ) ;
158162
159163 for i in 0 ..array. length ( ) {
160164 let item = array. get ( i) ;
161- let js_digest: JsDigest = JsCast :: unchecked_into ( item) ;
165+ let js_digest: JsDigest =
166+ item. dyn_into ( )
167+ . map_err ( |value| JsStorageError :: UnexpectedJsType {
168+ expected : "Digest" ,
169+ value,
170+ } ) ?;
162171 let digest: Digest < T > = WasmDigest :: from ( & js_digest) . into ( ) ;
163172 result. insert ( digest) ;
164173 }
165174
166- result
175+ Ok ( result)
167176}
168177
169178impl Storage < Local > for JsStorage {
@@ -265,7 +274,13 @@ impl Storage<Local> for JsStorage {
265274 return Ok ( None ) ;
266275 }
267276
268- let commit_with_blob: JsCommitWithBlob = js_value. unchecked_into ( ) ;
277+ let commit_with_blob: JsCommitWithBlob =
278+ js_value
279+ . dyn_into ( )
280+ . map_err ( |value| JsStorageError :: UnexpectedJsType {
281+ expected : "CommitWithBlob" ,
282+ value,
283+ } ) ?;
269284 let wasm_commit: WasmCommitWithBlob = ( & commit_with_blob) . into ( ) ;
270285 let signed: Signed < LooseCommit > = wasm_commit. signed ( ) . into ( ) ;
271286 let blob = Blob :: new ( wasm_commit. blob ( ) . to_vec ( ) ) ;
@@ -286,7 +301,7 @@ impl Storage<Local> for JsStorage {
286301 let js_value = JsFuture :: from ( js_promise)
287302 . await
288303 . map_err ( JsStorageError :: JsError ) ?;
289- Ok ( parse_digest_array ( & js_value) )
304+ parse_digest_array ( & js_value)
290305 } )
291306 }
292307
@@ -307,7 +322,12 @@ impl Storage<Local> for JsStorage {
307322
308323 for i in 0 ..array. length ( ) {
309324 let item = array. get ( i) ;
310- let commit_with_blob: JsCommitWithBlob = item. unchecked_into ( ) ;
325+ let commit_with_blob: JsCommitWithBlob =
326+ item. dyn_into ( )
327+ . map_err ( |value| JsStorageError :: UnexpectedJsType {
328+ expected : "CommitWithBlob" ,
329+ value,
330+ } ) ?;
311331 let wasm_commit: WasmCommitWithBlob = ( & commit_with_blob) . into ( ) ;
312332 let signed: Signed < LooseCommit > = wasm_commit. signed ( ) . into ( ) ;
313333 let blob = Blob :: new ( wasm_commit. blob ( ) . to_vec ( ) ) ;
@@ -397,7 +417,13 @@ impl Storage<Local> for JsStorage {
397417 return Ok ( None ) ;
398418 }
399419
400- let fragment_with_blob: JsFragmentWithBlob = js_value. unchecked_into ( ) ;
420+ let fragment_with_blob: JsFragmentWithBlob =
421+ js_value
422+ . dyn_into ( )
423+ . map_err ( |value| JsStorageError :: UnexpectedJsType {
424+ expected : "FragmentWithBlob" ,
425+ value,
426+ } ) ?;
401427 let wasm_fragment: WasmFragmentWithBlob = ( & fragment_with_blob) . into ( ) ;
402428 let signed: Signed < Fragment > = wasm_fragment. signed ( ) . into ( ) ;
403429 let blob = Blob :: new ( wasm_fragment. blob ( ) . to_vec ( ) ) ;
@@ -418,7 +444,7 @@ impl Storage<Local> for JsStorage {
418444 let js_value = JsFuture :: from ( js_promise)
419445 . await
420446 . map_err ( JsStorageError :: JsError ) ?;
421- Ok ( parse_digest_array ( & js_value) )
447+ parse_digest_array ( & js_value)
422448 } )
423449 }
424450
@@ -439,7 +465,12 @@ impl Storage<Local> for JsStorage {
439465
440466 for i in 0 ..array. length ( ) {
441467 let item = array. get ( i) ;
442- let fragment_with_blob: JsFragmentWithBlob = item. unchecked_into ( ) ;
468+ let fragment_with_blob: JsFragmentWithBlob =
469+ item. dyn_into ( )
470+ . map_err ( |value| JsStorageError :: UnexpectedJsType {
471+ expected : "FragmentWithBlob" ,
472+ value,
473+ } ) ?;
443474 let wasm_fragment: WasmFragmentWithBlob = ( & fragment_with_blob) . into ( ) ;
444475 let signed: Signed < Fragment > = wasm_fragment. signed ( ) . into ( ) ;
445476 let blob = Blob :: new ( wasm_fragment. blob ( ) . to_vec ( ) ) ;
@@ -550,6 +581,15 @@ pub enum JsStorageError {
550581 /// The `JsValue` could not be converted into an array of `SedimentreeId`s.
551582 #[ error( "Value was not an array of SedimentreeIds: {0:?}" ) ]
552583 NotSedimentreeIdArray ( #[ from] WasmConvertJsValueToSedimentreeIdArrayError ) ,
584+
585+ /// A JS value could not be cast to the expected type.
586+ #[ error( "JS type cast failed: expected {expected}, got {value:?}" ) ]
587+ UnexpectedJsType {
588+ /// The type name that was expected.
589+ expected : & ' static str ,
590+ /// The actual JS value received.
591+ value : JsValue ,
592+ } ,
553593}
554594
555595impl From < JsStorageError > for JsValue {
0 commit comments