@@ -830,20 +830,7 @@ impl InspectionUnavailable {
830830 remedy : remedy. to_owned ( ) ,
831831 }
832832 }
833- }
834833
835- /// An inspection that could not complete, keeping the cause in the reason. The
836- /// cause comes from spawning the tool, its timeout, temporary files and the
837- /// report parse; none of those messages carries a configured value.
838- fn inspection_failed ( field : & str , action : & str , error : & anyhow:: Error ) -> InspectionUnavailable {
839- InspectionUnavailable :: new (
840- field,
841- & format ! ( "The selected `caseworkctl` helper could not {action}: {error:#}." ) ,
842- "Install the matching Casework tools or provide RSTACK_CASEWORKCTL_BIN, then run the check again." ,
843- )
844- }
845-
846- impl InspectionUnavailable {
847834 pub ( super ) fn field ( & self ) -> & str {
848835 & self . field
849836 }
@@ -857,6 +844,28 @@ impl InspectionUnavailable {
857844 }
858845}
859846
847+ /// The error for an inspection that could not complete. An interrupt is the
848+ /// operator's request and stays as it is. Any other failure is an unavailable
849+ /// inspection whose reason keeps the cause; the cause comes from spawning the
850+ /// tool, its timeout, temporary files and the report parse, and none of those
851+ /// messages carries a configured value.
852+ fn inspection_failed (
853+ field : & str ,
854+ action : & str ,
855+ error : anyhow:: Error ,
856+ terminate : & AtomicBool ,
857+ ) -> anyhow:: Error {
858+ if terminate. load ( Ordering :: Relaxed ) {
859+ return error;
860+ }
861+ InspectionUnavailable :: new (
862+ field,
863+ & format ! ( "The selected `caseworkctl` helper could not {action}: {error:#}." ) ,
864+ "Install the matching Casework tools or provide RSTACK_CASEWORKCTL_BIN, then run the check again." ,
865+ )
866+ . into ( )
867+ }
868+
860869struct SelectedProduct {
861870 field : String ,
862871 root : PathBuf ,
@@ -1089,9 +1098,12 @@ fn casework_principals(
10891098 ) . into ( ) ) ;
10901099 }
10911100 Err ( error) => {
1092- return Err (
1093- inspection_failed ( & project. field , "inspect the Casework project" , & error) . into ( ) ,
1094- ) ;
1101+ return Err ( inspection_failed (
1102+ & project. field ,
1103+ "inspect the Casework project" ,
1104+ error,
1105+ terminate,
1106+ ) ) ;
10951107 }
10961108 } ;
10971109 let status_profile = plan
@@ -1279,7 +1291,7 @@ fn check_casework_binding(
12791291 } ) ( ) ;
12801292 let ( status, report) = match checked {
12811293 Ok ( checked) => checked,
1282- Err ( error) => return Err ( inspection_failed ( & project. field , action, & error) . into ( ) ) ,
1294+ Err ( error) => return Err ( inspection_failed ( & project. field , action, error, terminate ) ) ,
12831295 } ;
12841296 match casework_binding_check ( status. code ( ) , & report, & binding. id ) {
12851297 BindingCheck :: Accepted => Ok ( ( ) ) ,
@@ -1295,9 +1307,9 @@ fn check_casework_binding(
12951307 BindingCheck :: Unchecked => Err ( inspection_failed (
12961308 & project. field ,
12971309 action,
1298- & anyhow:: anyhow!( "caseworkctl check did not report a result for the binding" ) ,
1299- )
1300- . into ( ) ) ,
1310+ anyhow:: anyhow!( "caseworkctl check did not report a result for the binding" ) ,
1311+ terminate ,
1312+ ) ) ,
13011313 }
13021314}
13031315
@@ -2557,13 +2569,42 @@ mod tests {
25572569 let terminate = AtomicBool :: new ( false ) ;
25582570 let missing = Path :: new ( "/nonexistent/caseworkctl" ) ;
25592571 let error = explain_casework_facts ( missing, Path :: new ( "." ) , & terminate) . unwrap_err ( ) ;
2560- let reason = inspection_failed ( "products[0]" , "inspect the Casework project" , & error) ;
2572+ let failed = inspection_failed (
2573+ "products[0]" ,
2574+ "inspect the Casework project" ,
2575+ error,
2576+ & terminate,
2577+ ) ;
2578+ assert_eq ! ( class( & failed) , "operational" ) ;
2579+ let reason = failed
2580+ . downcast_ref :: < InspectionUnavailable > ( )
2581+ . expect ( "an unavailable inspection" )
2582+ . reason ( ) ;
25612583 assert ! (
2562- reason. reason ( ) . contains(
2584+ reason. contains(
25632585 "could not inspect the Casework project: cannot start caseworkctl explain"
25642586 ) ,
2565- "{}" ,
2566- reason. reason( )
2587+ "{reason}"
2588+ ) ;
2589+ }
2590+
2591+ #[ test]
2592+ fn an_interrupted_inspection_stays_the_operators_request ( ) {
2593+ let class =
2594+ |error : & anyhow:: Error | super :: super :: error_report ( error) . 0 [ "error" ] [ "class" ] . clone ( ) ;
2595+ let terminate = AtomicBool :: new ( true ) ;
2596+ let interrupted = anyhow:: anyhow!( "development product inspection was interrupted" ) ;
2597+ let failed = inspection_failed (
2598+ "products[0]" ,
2599+ "inspect the Casework project" ,
2600+ interrupted,
2601+ & terminate,
2602+ ) ;
2603+ assert ! ( !failed. is:: <InspectionUnavailable >( ) ) ;
2604+ assert_eq ! ( class( & failed) , "domain" ) ;
2605+ assert_eq ! (
2606+ failed. to_string( ) ,
2607+ "development product inspection was interrupted"
25672608 ) ;
25682609 }
25692610
0 commit comments