@@ -504,21 +504,27 @@ impl LoroDoc {
504504 let mut style_config = StyleConfigMap :: new ( ) ;
505505 // read key value pair in styles
506506 for key in Reflect :: own_keys ( & styles) ?. iter ( ) {
507- let value = Reflect :: get ( & styles, & key) . unwrap ( ) ;
508- let key = key. as_string ( ) . unwrap ( ) ;
507+ let value = Reflect :: get ( & styles, & key) ?;
508+ let key = key
509+ . as_string ( )
510+ . ok_or_else ( || JsError :: new ( "Text style key must be a string" ) ) ?;
509511 // Assert value is an object, otherwise throw an error with desc
510512 if !value. is_object ( ) {
511513 return Err ( "Text style config format error" . into ( ) ) ;
512514 }
513515 // read expand value from value
514- let expand = Reflect :: get ( & value, & "expand" . into ( ) ) . expect ( "`expand` not specified" ) ;
515- let expand_str = expand. as_string ( ) . unwrap ( ) ;
516+ let expand = Reflect :: get ( & value, & "expand" . into ( ) )
517+ . map_err ( |_| JsError :: new ( "`expand` not specified" ) ) ?;
518+ let expand_str = expand
519+ . as_string ( )
520+ . ok_or_else ( || JsError :: new ( "`expand` must be a string" ) ) ?;
516521 // read allowOverlap value from value
517522 style_config. insert (
518523 key. into ( ) ,
519524 StyleConfig {
520- expand : ExpandType :: try_from_str ( & expand_str)
521- . expect ( "`expand` must be one of `none`, `start`, `end`, `both`" ) ,
525+ expand : ExpandType :: try_from_str ( & expand_str) . ok_or_else ( || {
526+ JsError :: new ( "`expand` must be one of `none`, `start`, `end`, `both`" )
527+ } ) ?,
522528 } ,
523529 ) ;
524530 }
@@ -538,11 +544,15 @@ impl LoroDoc {
538544 self . 0 . config_default_text_style ( None ) ;
539545 } else {
540546 let value = style. obj ;
541- let expand = Reflect :: get ( & value, & "expand" . into ( ) ) . expect ( "`expand` not specified" ) ;
542- let expand_str = expand. as_string ( ) . unwrap ( ) ;
547+ let expand = Reflect :: get ( & value, & "expand" . into ( ) )
548+ . map_err ( |_| JsError :: new ( "`expand` not specified" ) ) ?;
549+ let expand_str = expand
550+ . as_string ( )
551+ . ok_or_else ( || JsError :: new ( "`expand` must be a string" ) ) ?;
543552
544- style_config. expand = ExpandType :: try_from_str ( & expand_str)
545- . expect ( "`expand` must be one of `none`, `start`, `end`, `both`" ) ;
553+ style_config. expand = ExpandType :: try_from_str ( & expand_str) . ok_or_else ( || {
554+ JsError :: new ( "`expand` must be one of `none`, `start`, `end`, `both`" )
555+ } ) ?;
546556
547557 self . 0 . config_default_text_style ( Some ( style_config) ) ;
548558 }
@@ -700,40 +710,38 @@ impl LoroDoc {
700710 Err ( _) => return Err ( JsValue :: from_str ( "Expected a function" ) ) ,
701711 } ;
702712 let observer = observer:: Observer :: new ( f) ;
713+ let ids: Result < Vec < _ > , _ > = ids. into_iter ( ) . map ( js_id_to_id) . collect ( ) ;
714+ let ids = ids?;
703715 self . 0
704- . travel_change_ancestors (
705- & ids. into_iter ( )
706- . map ( |id| js_id_to_id ( id) . unwrap ( ) )
707- . collect :: < Vec < _ > > ( ) ,
708- & mut |meta| {
709- let res = observer
710- . call1 (
711- & ChangeMeta {
712- lamport : meta. lamport ,
713- length : meta. len as u32 ,
714- peer : meta. id . peer . to_string ( ) ,
715- counter : meta. id . counter ,
716- deps : meta
717- . deps
718- . iter ( )
719- . map ( |id| StringID {
720- peer : id. peer . to_string ( ) ,
721- counter : id. counter ,
722- } )
723- . collect ( ) ,
724- timestamp : meta. timestamp as f64 ,
725- message : meta. message ,
726- }
727- . to_js ( ) ,
728- )
729- . unwrap ( ) ;
730- if res. as_bool ( ) . unwrap ( ) {
731- ControlFlow :: Continue ( ( ) )
732- } else {
733- ControlFlow :: Break ( ( ) )
716+ . travel_change_ancestors ( & ids, & mut |meta| {
717+ let res = match observer. call1 (
718+ & ChangeMeta {
719+ lamport : meta. lamport ,
720+ length : meta. len as u32 ,
721+ peer : meta. id . peer . to_string ( ) ,
722+ counter : meta. id . counter ,
723+ deps : meta
724+ . deps
725+ . iter ( )
726+ . map ( |id| StringID {
727+ peer : id. peer . to_string ( ) ,
728+ counter : id. counter ,
729+ } )
730+ . collect ( ) ,
731+ timestamp : meta. timestamp as f64 ,
732+ message : meta. message ,
734733 }
735- } ,
736- )
734+ . to_js ( ) ,
735+ ) {
736+ Ok ( v) => v,
737+ Err ( _) => return ControlFlow :: Continue ( ( ) ) ,
738+ } ;
739+ if res. as_bool ( ) . unwrap_or ( true ) {
740+ ControlFlow :: Continue ( ( ) )
741+ } else {
742+ ControlFlow :: Break ( ( ) )
743+ }
744+ } )
737745 . map_err ( |e| JsValue :: from ( e. to_string ( ) ) )
738746 }
739747
@@ -1814,8 +1822,8 @@ impl LoroDoc {
18141822 let ops = change
18151823 . ops ( )
18161824 . iter ( )
1817- . map ( |op| op. serialize ( & serializer) . unwrap ( ) )
1818- . collect :: < Vec < _ > > ( ) ;
1825+ . map ( |op| op. serialize ( & serializer) )
1826+ . collect :: < Result < Vec < _ > , _ > > ( ) ? ;
18191827
18201828 Ok ( ops)
18211829 }
@@ -2361,7 +2369,10 @@ impl LoroText {
23612369 } ;
23622370 let context = JsValue :: NULL ;
23632371 self . handler . iter ( |c| {
2364- let result = callback. call1 ( & context, & JsValue :: from ( c) ) . unwrap ( ) ;
2372+ let result = match callback. call1 ( & context, & JsValue :: from ( c) ) {
2373+ Ok ( v) => v,
2374+ Err ( _) => return true ,
2375+ } ;
23652376 match result. as_bool ( ) {
23662377 Some ( true ) => true ,
23672378 Some ( false ) => false ,
@@ -4126,7 +4137,10 @@ impl LoroTreeNode {
41264137 . get_all_hierarchy_nodes_under ( TreeParentId :: Node ( self . id ) ) ;
41274138 let node = TreeNodeWithChildren {
41284139 id : self . id ,
4129- parent : self . tree . get_node_parent ( & self . id ) . unwrap ( ) ,
4140+ parent : self
4141+ . tree
4142+ . get_node_parent ( & self . id )
4143+ . ok_or_else ( || JsError :: new ( "Tree node parent not found" ) ) ?,
41304144 fractional_index : self
41314145 . tree
41324146 . get_position_by_tree_id ( & self . id )
@@ -4323,14 +4337,17 @@ impl LoroTree {
43234337 #[ wasm_bindgen( js_name = "has" ) ]
43244338 pub fn contains ( & self , target : & JsTreeID ) -> bool {
43254339 let target: JsValue = target. into ( ) ;
4326- self . handler . contains ( target. try_into ( ) . unwrap ( ) )
4340+ match TreeID :: try_from ( target) {
4341+ Ok ( id) => self . handler . contains ( id) ,
4342+ Err ( _) => false ,
4343+ }
43274344 }
43284345
43294346 /// Return `None` if the node is not exist, otherwise return `Some(true)` if the node is deleted.
43304347 #[ wasm_bindgen( js_name = "isNodeDeleted" ) ]
43314348 pub fn is_node_deleted ( & self , target : & JsTreeID ) -> JsResult < bool > {
43324349 let target: JsValue = target. into ( ) ;
4333- let target = TreeID :: try_from ( target) . unwrap ( ) ;
4350+ let target = TreeID :: try_from ( target) ? ;
43344351 let ans = self . handler . is_node_deleted ( & target) ?;
43354352 Ok ( ans)
43364353 }
@@ -4398,7 +4415,10 @@ impl LoroTree {
43984415 . unwrap_or ( JsValue :: undefined ( ) ) ;
43994416 let index = v. index ;
44004417 let position = v. fractional_index . to_string ( ) ;
4401- let map: LoroMap = self . get_node_by_id ( & id) . unwrap ( ) . data ( ) ?;
4418+ let map: LoroMap = self
4419+ . get_node_by_id ( & id)
4420+ . ok_or_else ( || JsError :: new ( "Tree node not found" ) ) ?
4421+ . data ( ) ?;
44024422 let obj = Object :: new ( ) ;
44034423 js_sys:: Reflect :: set ( & obj, & "id" . into ( ) , & id) ?;
44044424 js_sys:: Reflect :: set ( & obj, & "parent" . into ( ) , & parent) ?;
0 commit comments