@@ -446,12 +446,12 @@ def _establish_hooks_and_provider(
446
446
447
447
def _assert_provider_status (
448
448
self ,
449
- ) -> None :
449
+ ) -> typing . Optional [ OpenFeatureError ] :
450
450
status = self .get_provider_status ()
451
451
if status == ProviderStatus .NOT_READY :
452
- raise ProviderNotReadyError ()
452
+ return ProviderNotReadyError ()
453
453
if status == ProviderStatus .FATAL :
454
- raise ProviderFatalError ()
454
+ return ProviderFatalError ()
455
455
return None
456
456
457
457
def _before_hooks_and_merge_context (
@@ -511,7 +511,22 @@ async def evaluate_flag_details_async(
511
511
)
512
512
513
513
try :
514
- self ._assert_provider_status ()
514
+ if provider_err := self ._assert_provider_status ():
515
+ error_hooks (
516
+ flag_type ,
517
+ hook_context ,
518
+ provider_err ,
519
+ reversed_merged_hooks ,
520
+ hook_hints ,
521
+ )
522
+ flag_evaluation = FlagEvaluationDetails (
523
+ flag_key = flag_key ,
524
+ value = default_value ,
525
+ reason = Reason .ERROR ,
526
+ error_code = provider_err .error_code ,
527
+ error_message = provider_err .error_message ,
528
+ )
529
+ return flag_evaluation
515
530
516
531
merged_context = self ._before_hooks_and_merge_context (
517
532
flag_type ,
@@ -528,6 +543,11 @@ async def evaluate_flag_details_async(
528
543
default_value ,
529
544
merged_context ,
530
545
)
546
+ if err := flag_evaluation .get_exception ():
547
+ error_hooks (
548
+ flag_type , hook_context , err , reversed_merged_hooks , hook_hints
549
+ )
550
+ return flag_evaluation
531
551
532
552
after_hooks (
533
553
flag_type ,
@@ -607,7 +627,22 @@ def evaluate_flag_details(
607
627
)
608
628
609
629
try :
610
- self ._assert_provider_status ()
630
+ if provider_err := self ._assert_provider_status ():
631
+ error_hooks (
632
+ flag_type ,
633
+ hook_context ,
634
+ provider_err ,
635
+ reversed_merged_hooks ,
636
+ hook_hints ,
637
+ )
638
+ flag_evaluation = FlagEvaluationDetails (
639
+ flag_key = flag_key ,
640
+ value = default_value ,
641
+ reason = Reason .ERROR ,
642
+ error_code = provider_err .error_code ,
643
+ error_message = provider_err .error_message ,
644
+ )
645
+ return flag_evaluation
611
646
612
647
merged_context = self ._before_hooks_and_merge_context (
613
648
flag_type ,
@@ -624,6 +659,12 @@ def evaluate_flag_details(
624
659
default_value ,
625
660
merged_context ,
626
661
)
662
+ if err := flag_evaluation .get_exception ():
663
+ error_hooks (
664
+ flag_type , hook_context , err , reversed_merged_hooks , hook_hints
665
+ )
666
+ flag_evaluation .value = default_value
667
+ return flag_evaluation
627
668
628
669
after_hooks (
629
670
flag_type ,
@@ -693,27 +734,33 @@ async def _create_provider_evaluation_async(
693
734
}
694
735
get_details_callable = get_details_callables_async .get (flag_type )
695
736
if not get_details_callable :
696
- raise GeneralError (error_message = "Unknown flag type" )
737
+ return FlagEvaluationDetails (
738
+ flag_key = flag_key ,
739
+ value = default_value ,
740
+ reason = Reason .ERROR ,
741
+ error_code = ErrorCode .GENERAL ,
742
+ error_message = "Unknown flag type" ,
743
+ )
697
744
698
745
resolution = await get_details_callable (
699
746
flag_key = flag_key ,
700
747
default_value = default_value ,
701
748
evaluation_context = evaluation_context ,
702
749
)
703
- resolution .raise_for_error ()
750
+ if resolution .error_code :
751
+ return resolution .to_flag_evaluation_details (flag_key )
704
752
705
753
# we need to check the get_args to be compatible with union types.
706
- _typecheck_flag_value (resolution .value , flag_type )
754
+ if err := _typecheck_flag_value (value = resolution .value , flag_type = flag_type ):
755
+ return FlagEvaluationDetails (
756
+ flag_key = flag_key ,
757
+ value = resolution .value ,
758
+ reason = Reason .ERROR ,
759
+ error_code = err .error_code ,
760
+ error_message = err .error_message ,
761
+ )
707
762
708
- return FlagEvaluationDetails (
709
- flag_key = flag_key ,
710
- value = resolution .value ,
711
- variant = resolution .variant ,
712
- flag_metadata = resolution .flag_metadata or {},
713
- reason = resolution .reason ,
714
- error_code = resolution .error_code ,
715
- error_message = resolution .error_message ,
716
- )
763
+ return resolution .to_flag_evaluation_details (flag_key )
717
764
718
765
def _create_provider_evaluation (
719
766
self ,
@@ -743,27 +790,33 @@ def _create_provider_evaluation(
743
790
744
791
get_details_callable = get_details_callables .get (flag_type )
745
792
if not get_details_callable :
746
- raise GeneralError (error_message = "Unknown flag type" )
793
+ return FlagEvaluationDetails (
794
+ flag_key = flag_key ,
795
+ value = default_value ,
796
+ reason = Reason .ERROR ,
797
+ error_code = ErrorCode .GENERAL ,
798
+ error_message = "Unknown flag type" ,
799
+ )
747
800
748
801
resolution = get_details_callable (
749
802
flag_key = flag_key ,
750
803
default_value = default_value ,
751
804
evaluation_context = evaluation_context ,
752
805
)
753
- resolution .raise_for_error ()
806
+ if resolution .error_code :
807
+ return resolution .to_flag_evaluation_details (flag_key )
754
808
755
809
# we need to check the get_args to be compatible with union types.
756
- _typecheck_flag_value (resolution .value , flag_type )
810
+ if err := _typecheck_flag_value (value = resolution .value , flag_type = flag_type ):
811
+ return FlagEvaluationDetails (
812
+ flag_key = flag_key ,
813
+ value = resolution .value ,
814
+ reason = Reason .ERROR ,
815
+ error_code = err .error_code ,
816
+ error_message = err .error_message ,
817
+ )
757
818
758
- return FlagEvaluationDetails (
759
- flag_key = flag_key ,
760
- value = resolution .value ,
761
- variant = resolution .variant ,
762
- flag_metadata = resolution .flag_metadata or {},
763
- reason = resolution .reason ,
764
- error_code = resolution .error_code ,
765
- error_message = resolution .error_message ,
766
- )
819
+ return resolution .to_flag_evaluation_details (flag_key )
767
820
768
821
def add_handler (self , event : ProviderEvent , handler : EventHandler ) -> None :
769
822
_event_support .add_client_handler (self , event , handler )
@@ -772,7 +825,9 @@ def remove_handler(self, event: ProviderEvent, handler: EventHandler) -> None:
772
825
_event_support .remove_client_handler (self , event , handler )
773
826
774
827
775
- def _typecheck_flag_value (value : typing .Any , flag_type : FlagType ) -> None :
828
+ def _typecheck_flag_value (
829
+ value : typing .Any , flag_type : FlagType
830
+ ) -> typing .Optional [OpenFeatureError ]:
776
831
type_map : TypeMap = {
777
832
FlagType .BOOLEAN : bool ,
778
833
FlagType .STRING : str ,
@@ -782,6 +837,7 @@ def _typecheck_flag_value(value: typing.Any, flag_type: FlagType) -> None:
782
837
}
783
838
_type = type_map .get (flag_type )
784
839
if not _type :
785
- raise GeneralError (error_message = "Unknown flag type" )
840
+ return GeneralError (error_message = "Unknown flag type" )
786
841
if not isinstance (value , _type ):
787
- raise TypeMismatchError (f"Expected type { _type } but got { type (value )} " )
842
+ return TypeMismatchError (f"Expected type { _type } but got { type (value )} " )
843
+ return None
0 commit comments