Encode missing input file failures with FailureDetails

RELNOTES: None.
PiperOrigin-RevId: 315812543
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionException.java b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionException.java
index 8c254e1..b529b89 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionException.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionException.java
@@ -94,12 +94,13 @@
       String message,
       ActionAnalysisMetadata action,
       NestedSet<Cause> rootCauses,
-      boolean catastrophe) {
+      boolean catastrophe,
+      DetailedExitCode detailedExitCode) {
     super(message);
     this.action = action;
     this.rootCauses = rootCauses;
     this.catastrophe = catastrophe;
-    this.detailedExitCode = DetailedExitCode.justExitCode(ExitCode.BUILD_FAILURE);
+    this.detailedExitCode = detailedExitCode;
   }
 
   public ActionExecutionException(
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java
index b25b364..fc60abd 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionExecutionFunction.java
@@ -67,6 +67,9 @@
 import com.google.devtools.build.lib.profiler.ProfilerTask;
 import com.google.devtools.build.lib.profiler.SilentCloseable;
 import com.google.devtools.build.lib.rules.cpp.IncludeScannable;
+import com.google.devtools.build.lib.server.FailureDetails.Execution;
+import com.google.devtools.build.lib.server.FailureDetails.Execution.Code;
+import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
 import com.google.devtools.build.lib.skyframe.ActionRewindStrategy.RewindPlan;
 import com.google.devtools.build.lib.skyframe.ArtifactFunction.MissingFileArtifactValue;
 import com.google.devtools.build.lib.skyframe.ArtifactNestedSetFunction.ArtifactNestedSetEvalException;
@@ -1357,11 +1360,7 @@
     }
 
     if (!missingArtifactCauses.isEmpty()) {
-      throw new ActionExecutionException(
-          missingArtifactCauses.size() + " input file(s) do not exist",
-          action,
-          NestedSetBuilder.wrap(Order.STABLE_ORDER, missingArtifactCauses),
-          /*catastrophe=*/ false);
+      throw createMissingInputsException(action, missingArtifactCauses);
     }
     return accumulateInputResultsFactory.create(
         inputArtifactData, expandedArtifacts, filesetsInsideRunfiles, topLevelFilesets);
@@ -1718,11 +1717,7 @@
               action,
               null);
         }
-        throw new ActionExecutionException(
-            missingArtifactCauses.size() + " input file(s) do not exist",
-            action,
-            NestedSetBuilder.wrap(Order.STABLE_ORDER, missingArtifactCauses),
-            /*catastrophe=*/ false);
+        throw createMissingInputsException(action, missingArtifactCauses);
       }
     }
 
@@ -1759,4 +1754,19 @@
       }
     }
   }
+
+  private static ActionExecutionException createMissingInputsException(
+      Action action, List<LabelCause> missingArtifactCauses) {
+    String message = missingArtifactCauses.size() + " input file(s) do not exist";
+    return new ActionExecutionException(
+        message,
+        action,
+        NestedSetBuilder.wrap(Order.STABLE_ORDER, missingArtifactCauses),
+        /*catastrophe=*/ false,
+        DetailedExitCode.of(
+            FailureDetail.newBuilder()
+                .setMessage(message)
+                .setExecution(Execution.newBuilder().setCode(Code.ACTION_INPUT_FILES_MISSING))
+                .build()));
+  }
 }
diff --git a/src/main/protobuf/failure_details.proto b/src/main/protobuf/failure_details.proto
index 4343486..9c31fd2 100644
--- a/src/main/protobuf/failure_details.proto
+++ b/src/main/protobuf/failure_details.proto
@@ -349,6 +349,7 @@
     PERSISTENT_ACTION_OUTPUT_DIRECTORY_CREATION_FAILURE = 6
         [(metadata) = { exit_code: 36 }];
     LOCAL_OUTPUT_DIRECTORY_SYMLINK_FAILURE = 7 [(metadata) = { exit_code: 36 }];
+    ACTION_INPUT_FILES_MISSING = 8 [(metadata) = { exit_code: 1 }];
   }
 
   Code code = 1;