Allow use of Exceptions to exit early out of configured-target creation, instead of passing and checking null in all helpers.
Demonstrates this pattern usage in a few select rules (e.g. AndroidBinary) where this was particularly egregious.
There are many places which can benefit from this pattern -- this change doesn't try to fix them all at once.

--
MOS_MIGRATED_REVID=123012378
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 20ff73c..f7671a2 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -65,6 +65,7 @@
 import com.google.devtools.build.lib.packages.RawAttributeMapper;
 import com.google.devtools.build.lib.packages.Rule;
 import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
 import com.google.devtools.build.lib.packages.RuleErrorConsumer;
 import com.google.devtools.build.lib.packages.Target;
 import com.google.devtools.build.lib.packages.TargetUtils;
@@ -289,6 +290,16 @@
   public boolean hasErrors() {
     return getAnalysisEnvironment().hasErrors();
   }
+  
+  /**
+   * No-op if {@link #hasErrors} is false, throws {@link RuleErrorException} if it is true.
+   * This provides a convenience to early-exit of configured target creation if there are errors.
+   */
+  public void assertNoErrors() throws RuleErrorException {
+    if (hasErrors()) {
+      throw new RuleErrorException();
+    }
+  }
 
   /**
    * Returns an immutable map from attribute name to list of configured targets for that attribute.
@@ -406,6 +417,17 @@
   public void ruleError(String message) {
     reporter.ruleError(message);
   }
+  
+  /**
+   * Convenience function to report non-attribute-specific errors in the current rule and then
+   * throw a {@link RuleErrorException}, immediately exiting the build invocation. Alternatively,
+   * invoke {@link #ruleError} instead to collect additional error information before ending the
+   * invocation.
+   */
+  public void throwWithRuleError(String message) throws RuleErrorException {
+    reporter.ruleError(message);
+    throw new RuleErrorException();
+  }
 
   /**
    * Convenience function for subclasses to report non-attribute-specific
@@ -429,6 +451,20 @@
   }
 
   /**
+   * Convenience function to report attribute-specific errors in the current rule, and then throw a
+   * {@link RuleErrorException}, immediately exiting the build invocation. Alternatively, invoke
+   * {@link #attributeError} instead to collect additional error information before ending the
+   * invocation.
+   *
+   * <p>If the name of the attribute starts with <code>$</code>
+   * it is replaced with a string <code>(an implicit dependency)</code>.
+   */
+  public void throwWithAttributeError(String attrName, String message) throws RuleErrorException {
+    reporter.attributeError(attrName, message);
+    throw new RuleErrorException();
+  }
+
+  /**
    * Like attributeError, but does not mark the configured target as errored.
    *
    * <p>If the name of the attribute starts with <code>$</code>