|
60 | 60 | from codeflash.context import code_context_extractor |
61 | 61 | from codeflash.context.unused_definition_remover import detect_unused_helper_functions, revert_unused_helper_functions |
62 | 62 | from codeflash.discovery.functions_to_optimize import was_function_previously_optimized |
63 | | -from codeflash.either import Failure, Success, is_successful |
| 63 | +from codeflash.either import CodeflashError, Failure, Success, is_successful |
| 64 | +from codeflash.errors.errors import ( |
| 65 | + baseline_establishment_failed_error, |
| 66 | + behavioral_test_failure_error, |
| 67 | + code_context_extraction_failed_error, |
| 68 | + coverage_threshold_not_met_error, |
| 69 | + function_optimization_attempted_error, |
| 70 | + no_best_optimization_found_error, |
| 71 | + no_optimizations_generated_error, |
| 72 | + no_tests_generated_error, |
| 73 | + test_confidence_threshold_not_met_error, |
| 74 | + test_result_didnt_match_error, |
| 75 | +) |
64 | 76 | from codeflash.models.ExperimentMetadata import ExperimentMetadata |
65 | 77 | from codeflash.models.models import ( |
66 | 78 | BestOptimization, |
@@ -252,14 +264,18 @@ def can_be_optimized(self) -> Result[tuple[bool, CodeOptimizationContext, dict[P |
252 | 264 | has_any_async_functions(code_string.code) for code_string in code_context.read_writable_code.code_strings |
253 | 265 | ) |
254 | 266 | if async_code: |
255 | | - return Failure("Codeflash does not support async functions in the code to optimize.") |
| 267 | + return Failure( |
| 268 | + CodeflashError( |
| 269 | + "ASYNC_CODE_ERROR", "Codeflash does not support async functions in the code to optimize." |
| 270 | + ) |
| 271 | + ) |
256 | 272 | # Random here means that we still attempt optimization with a fractional chance to see if |
257 | 273 | # last time we could not find an optimization, maybe this time we do. |
258 | 274 | # Random is before as a performance optimization, swapping the two 'and' statements has the same effect |
259 | 275 | if random.random() > REPEAT_OPTIMIZATION_PROBABILITY and was_function_previously_optimized( # noqa: S311 |
260 | 276 | self.function_to_optimize, code_context, self.args |
261 | 277 | ): |
262 | | - return Failure("Function optimization previously attempted, skipping.") |
| 278 | + return Failure(function_optimization_attempted_error()) |
263 | 279 |
|
264 | 280 | return Success((should_run_experiment, code_context, original_helper_code)) |
265 | 281 |
|
@@ -430,7 +446,7 @@ def optimize_function(self) -> Result[BestOptimization, str]: |
430 | 446 | if self.args.override_fixtures: |
431 | 447 | restore_conftest(original_conftest_content) |
432 | 448 | if not best_optimization: |
433 | | - return Failure(f"No best optimizations found for function {self.function_to_optimize.qualified_name}") |
| 449 | + return Failure(no_best_optimization_found_error(self.function_to_optimize.qualified_name)) |
434 | 450 | return Success(best_optimization) |
435 | 451 |
|
436 | 452 | def determine_best_candidate( |
@@ -852,7 +868,7 @@ def get_code_optimization_context(self) -> Result[CodeOptimizationContext, str]: |
852 | 868 | self.function_to_optimize, self.project_root |
853 | 869 | ) |
854 | 870 | except ValueError as e: |
855 | | - return Failure(str(e)) |
| 871 | + return Failure(code_context_extraction_failed_error(str(e))) |
856 | 872 |
|
857 | 873 | return Success( |
858 | 874 | CodeOptimizationContext( |
@@ -1012,7 +1028,7 @@ def generate_tests_and_optimizations( |
1012 | 1028 | # Retrieve results |
1013 | 1029 | candidates: list[OptimizedCandidate] = future_optimization_candidates.result() |
1014 | 1030 | if not candidates: |
1015 | | - return Failure(f"/!\\ NO OPTIMIZATIONS GENERATED for {self.function_to_optimize.function_name}") |
| 1031 | + return Failure(no_optimizations_generated_error(self.function_to_optimize.function_name)) |
1016 | 1032 |
|
1017 | 1033 | candidates_experiment = future_candidates_exp.result() if future_candidates_exp else None |
1018 | 1034 |
|
@@ -1040,7 +1056,7 @@ def generate_tests_and_optimizations( |
1040 | 1056 | ) |
1041 | 1057 | if not tests: |
1042 | 1058 | logger.warning(f"Failed to generate and instrument tests for {self.function_to_optimize.function_name}") |
1043 | | - return Failure(f"/!\\ NO TESTS GENERATED for {self.function_to_optimize.function_name}") |
| 1059 | + return Failure(no_tests_generated_error(self.function_to_optimize.function_name)) |
1044 | 1060 | function_to_concolic_tests, concolic_test_str = future_concolic_tests.result() |
1045 | 1061 | logger.info(f"Generated {len(tests)} tests for {self.function_to_optimize.function_name}") |
1046 | 1062 | console.rule() |
@@ -1100,14 +1116,21 @@ def setup_and_establish_baseline( |
1100 | 1116 | return Failure(baseline_result.failure()) |
1101 | 1117 |
|
1102 | 1118 | original_code_baseline, test_functions_to_remove = baseline_result.unwrap() |
1103 | | - if isinstance(original_code_baseline, OriginalCodeBaseline) and ( |
1104 | | - not coverage_critic(original_code_baseline.coverage_results, self.args.test_framework) |
1105 | | - or not quantity_of_tests_critic(original_code_baseline) |
1106 | | - ): |
1107 | | - if self.args.override_fixtures: |
1108 | | - restore_conftest(original_conftest_content) |
1109 | | - cleanup_paths(paths_to_cleanup) |
1110 | | - return Failure("The threshold for test confidence was not met.") |
| 1119 | + if isinstance(original_code_baseline, OriginalCodeBaseline): |
| 1120 | + error = None |
| 1121 | + sufficent_coverage = coverage_critic(original_code_baseline.coverage_results, self.args.test_framework) |
| 1122 | + sufficent_tests = quantity_of_tests_critic(original_code_baseline) |
| 1123 | + |
| 1124 | + if not sufficent_coverage: |
| 1125 | + error = coverage_threshold_not_met_error() |
| 1126 | + elif not sufficent_tests: |
| 1127 | + error = test_confidence_threshold_not_met_error() |
| 1128 | + |
| 1129 | + if error: |
| 1130 | + if self.args.override_fixtures: |
| 1131 | + restore_conftest(original_conftest_content) |
| 1132 | + cleanup_paths(paths_to_cleanup) |
| 1133 | + return Failure(error) |
1111 | 1134 |
|
1112 | 1135 | return Success( |
1113 | 1136 | ( |
@@ -1394,9 +1417,9 @@ def establish_original_code_baseline( |
1394 | 1417 | f"Couldn't run any tests for original function {self.function_to_optimize.function_name}. SKIPPING OPTIMIZING THIS FUNCTION." |
1395 | 1418 | ) |
1396 | 1419 | console.rule() |
1397 | | - return Failure("Failed to establish a baseline for the original code - bevhavioral tests failed.") |
| 1420 | + return Failure(behavioral_test_failure_error()) |
1398 | 1421 | if not coverage_critic(coverage_results, self.args.test_framework): |
1399 | | - return Failure("The threshold for test coverage was not met.") |
| 1422 | + return Failure(coverage_threshold_not_met_error()) |
1400 | 1423 | if test_framework == "pytest": |
1401 | 1424 | line_profile_results = self.line_profiler_step( |
1402 | 1425 | code_context=code_context, original_helper_code=original_helper_code, candidate_index=0 |
@@ -1456,7 +1479,7 @@ def establish_original_code_baseline( |
1456 | 1479 | console.rule() |
1457 | 1480 | success = False |
1458 | 1481 | if not success: |
1459 | | - return Failure("Failed to establish a baseline for the original code.") |
| 1482 | + return Failure(baseline_establishment_failed_error()) |
1460 | 1483 |
|
1461 | 1484 | loop_count = max([int(result.loop_index) for result in benchmarking_results.test_results]) |
1462 | 1485 | logger.info( |
@@ -1540,7 +1563,7 @@ def run_optimized_candidate( |
1540 | 1563 | else: |
1541 | 1564 | logger.info("Test results did not match the test results of the original code.") |
1542 | 1565 | console.rule() |
1543 | | - return Failure("Test results did not match the test results of the original code.") |
| 1566 | + return Failure(test_result_didnt_match_error()) |
1544 | 1567 |
|
1545 | 1568 | if test_framework == "pytest": |
1546 | 1569 | candidate_benchmarking_results, _ = self.run_and_parse_tests( |
|
0 commit comments