@@ -368,7 +368,11 @@ def add_options(self, config: "BaseOptions", combine_extends: bool = False) -> N
368368 if new is not None :
369369 setattr (self , f .name , new )
370370
371- def evaluated (self , verbose_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ) -> Self :
371+ def evaluated (
372+ self ,
373+ verbose_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ,
374+ error_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ,
375+ ) -> Self :
372376 if verbose_callback is not None :
373377 verbose_callback ("Evaluating options" )
374378
@@ -395,7 +399,11 @@ def evaluated(self, verbose_callback: Optional[Callable[[Union[str, Callable[[],
395399 },
396400 )
397401 except EvaluationError as e :
398- raise ValueError (f"Evaluation of '{ f .name } ' failed: { e !s} " ) from e
402+ message = f"Evaluation of '{ f .name } ' failed: { type (e ).__name__ } : { e } "
403+ if error_callback is None :
404+ raise ValueError (message ) from e
405+ error_callback (message )
406+
399407 return result
400408
401409
@@ -2199,15 +2207,17 @@ def save(self, path: "os.PathLike[str]") -> None:
21992207 f .write (tomli_w .dumps (as_dict (self , remove_defaults = True )))
22002208
22012209 def evaluated_with_env (
2202- self , verbose_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None
2210+ self ,
2211+ verbose_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ,
2212+ error_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ,
22032213 ) -> Self :
22042214 if self .env :
22052215 for k , v in self .env .items ():
22062216 os .environ [k ] = str (v )
22072217 if verbose_callback :
22082218 verbose_callback (lambda : f"Set environment variable `{ k } ` to `{ v } `" )
22092219
2210- return self .evaluated (verbose_callback )
2220+ return self .evaluated (verbose_callback , error_callback )
22112221
22122222
22132223@dataclass
@@ -2343,6 +2353,7 @@ def select_profiles(
23432353 self ,
23442354 * names : str ,
23452355 verbose_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ,
2356+ error_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ,
23462357 ) -> Dict [str , RobotProfile ]:
23472358 result : Dict [str , RobotProfile ] = {}
23482359
@@ -2373,7 +2384,12 @@ def select(name: str) -> None:
23732384 profile_names = [p for p in profiles .keys () if fnmatch .fnmatchcase (p , name )]
23742385
23752386 if not profile_names :
2376- raise ValueError (f"Can't find any profiles matching the pattern '{ name } '." )
2387+ message = f"Can't find any configuration profiles matching the pattern '{ name } '."
2388+ if error_callback is None :
2389+ raise ValueError (message )
2390+
2391+ error_callback (message )
2392+ return
23772393
23782394 for v in profile_names :
23792395 p = profiles [v ]
@@ -2391,8 +2407,20 @@ def select(name: str) -> None:
23912407 return result
23922408
23932409 def combine_profiles (
2394- self , * names : str , verbose_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None
2410+ self ,
2411+ * names : str ,
2412+ verbose_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ,
2413+ error_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ,
23952414 ) -> RobotBaseProfile :
2415+ return self .combine_profiles_ex (* names , verbose_callback = verbose_callback , error_callback = error_callback )[0 ]
2416+
2417+ def combine_profiles_ex (
2418+ self ,
2419+ * names : str ,
2420+ verbose_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ,
2421+ error_callback : Optional [Callable [[Union [str , Callable [[], Any ]]], None ]] = None ,
2422+ ) -> Tuple [RobotBaseProfile , Dict [str , RobotProfile ], List [str ]]:
2423+ enabled_profiles = []
23962424 type_hints = get_type_hints (RobotBaseProfile )
23972425 base_field_names = [f .name for f in dataclasses .fields (RobotBaseProfile )]
23982426
@@ -2410,7 +2438,9 @@ def combine_profiles(
24102438 }
24112439 )
24122440
2413- selected_profiles = self .select_profiles (* names , verbose_callback = verbose_callback )
2441+ selected_profiles = self .select_profiles (
2442+ * names , verbose_callback = verbose_callback , error_callback = error_callback
2443+ )
24142444 if verbose_callback :
24152445 if selected_profiles :
24162446 verbose_callback (f"Selected profiles: { ', ' .join (selected_profiles .keys ())} " )
@@ -2424,11 +2454,19 @@ def combine_profiles(
24242454 verbose_callback (f'Skipping profile "{ profile_name } " because it\' s disabled.' )
24252455 continue
24262456 except EvaluationError as e :
2427- raise ValueError (f'Error evaluating "enabled" condition for profile "{ profile_name } ": { e } ' ) from e
2457+ message = f'Error evaluating "enabled" condition for profile "{ profile_name } ": { e } '
2458+
2459+ if error_callback is None :
2460+ raise ValueError (message ) from e
2461+
2462+ error_callback (message )
2463+ continue
24282464
24292465 if verbose_callback :
24302466 verbose_callback (f'Using profile "{ profile_name } ".' )
24312467
2468+ enabled_profiles .append (profile_name )
2469+
24322470 if profile .env :
24332471 for k , v in profile .env .items ():
24342472 os .environ [k ] = str (v )
@@ -2482,4 +2520,4 @@ def combine_profiles(
24822520 if new is not None :
24832521 setattr (result , f .name , new )
24842522
2485- return result
2523+ return result , selected_profiles , enabled_profiles
0 commit comments