Properly handle exceptions that RecursivePkgFunction can encounter, instead of silently swallowing them.

The old behavior was simply incorrect on --keep_going builds because it meant any directory with an uncaught error caused all of its ancestors to not have any values. It wasn't noticed because SkyframeTargetPatternEvaluator was overly permissive in the errors it expects.

We also use a singleton for the empty RecursivePkgValue which might have a negligible (beneficial) memory impact.

--
MOS_MIGRATED_REVID=95037551
diff --git a/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
index c3faec8..68cb59a 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/SkyQueryEnvironment.java
@@ -354,6 +354,10 @@
           }
           result.put(pattern, targetsBuilder.build());
         } else {
+          // Because the graph was always initialized via a keep_going build, we know that the
+          // exception stored here must be a TargetParsingException. Thus the comment in
+          // SkyframeTargetPatternEvaluator#parseTargetPatternKeys describing the situation in which
+          // the exception acceptance must be looser does not apply here.
           targetParsingException =
               (TargetParsingException)
                   Preconditions.checkNotNull(graph.getException(patternKey), pattern);