@@ -21,7 +21,7 @@ use buck2_build_signals::NodeDuration;
21
21
use buck2_common:: events:: HasEvents ;
22
22
use buck2_core:: base_deferred_key:: BaseDeferredKey ;
23
23
use buck2_core:: target:: configured_target_label:: ConfiguredTargetLabel ;
24
- use buck2_data:: ActionErrorDiagnostics ;
24
+ use buck2_data:: { action_error_diagnostics , ActionErrorDiagnostics } ;
25
25
use buck2_data:: ActionSubErrors ;
26
26
use buck2_data:: ToProtoMessage ;
27
27
use buck2_events:: dispatch:: async_record_root_spans;
@@ -57,6 +57,7 @@ use crate::actions::error_handler::ActionSubErrorResult;
57
57
use crate :: actions:: error_handler:: StarlarkActionErrorContext ;
58
58
use crate :: actions:: execute:: action_executor:: ActionOutputs ;
59
59
use crate :: actions:: execute:: action_executor:: HasActionExecutor ;
60
+ use crate :: actions:: execute:: error:: ExecuteError ;
60
61
use crate :: actions:: RegisteredAction ;
61
62
use crate :: artifact_groups:: calculation:: ensure_artifact_group_staged;
62
63
use crate :: deferred:: calculation:: lookup_deferred_holder;
@@ -255,7 +256,10 @@ async fn build_action_no_redirect(
255
256
256
257
let last_command = commands. last ( ) . cloned ( ) ;
257
258
258
- let error_diagnostics = try_run_error_handler ( action. dupe ( ) , last_command. as_ref ( ) ) ;
259
+ let error_diagnostics = build_error_diagnostics (
260
+ & e,
261
+ try_run_error_handler ( action. dupe ( ) , last_command. as_ref ( ) )
262
+ ) ;
259
263
260
264
let e = ActionError :: new (
261
265
e,
@@ -357,10 +361,50 @@ async fn build_action_no_redirect(
357
361
} ,
358
362
spans,
359
363
} ) ?;
360
-
361
364
action_execution_data. action_result
362
365
}
363
366
367
+ fn build_error_diagnostics ( execute_error : & ExecuteError , error_diagnostics : Option < ActionErrorDiagnostics > ) -> Option < ActionErrorDiagnostics > {
368
+ let ExecuteError :: CommandExecutionError { error : Some ( command_execute_error) } = execute_error else {
369
+ return error_diagnostics;
370
+ } ;
371
+ let action_sub_error = || buck2_data:: ActionSubError {
372
+ category : "ServerMessage" . to_string ( ) ,
373
+ message : Some ( format ! ( "{}" , command_execute_error) ) ,
374
+ locations : None ,
375
+ } ;
376
+ if let Some ( inner_error_diagnostics) = & error_diagnostics {
377
+ if let Some ( error_diagnostics_data) = & inner_error_diagnostics. data {
378
+ match error_diagnostics_data {
379
+ action_error_diagnostics:: Data :: SubErrors ( action_sub_errors) => {
380
+ let sub_errors = action_sub_errors
381
+ . sub_errors
382
+ . iter ( )
383
+ . chain ( [ & action_sub_error ( ) ] )
384
+ . cloned ( )
385
+ . collect ( ) ;
386
+ Some ( ActionErrorDiagnostics {
387
+ data : Some ( action_error_diagnostics:: Data :: SubErrors ( ActionSubErrors { sub_errors } ) ) ,
388
+ } )
389
+ } ,
390
+ action_error_diagnostics:: Data :: HandlerInvocationError ( handler_error) => {
391
+ Some ( ActionErrorDiagnostics {
392
+ data : Some ( action_error_diagnostics:: Data :: HandlerInvocationError ( format ! ( "{}\n {}" , handler_error, command_execute_error) ) ) ,
393
+ } )
394
+ } ,
395
+ }
396
+ } else {
397
+ Some ( ActionErrorDiagnostics {
398
+ data : Some ( action_error_diagnostics:: Data :: SubErrors ( ActionSubErrors { sub_errors : vec ! [ action_sub_error( ) ] } ) ) ,
399
+ } )
400
+ }
401
+ } else {
402
+ Some ( ActionErrorDiagnostics {
403
+ data : Some ( action_error_diagnostics:: Data :: SubErrors ( ActionSubErrors { sub_errors : vec ! [ action_sub_error( ) ] } ) ) ,
404
+ } )
405
+ }
406
+ }
407
+
364
408
// Attempt to run the error handler if one was specified. Returns either the error diagnostics, or
365
409
// an actual error if the handler failed to run successfully.
366
410
fn try_run_error_handler (
0 commit comments