Convert binding exception to something that's actually caught in PackageFunction

--
MOS_MIGRATED_REVID=87967267
diff --git a/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java b/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
index 6f7b243..345c28a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
@@ -138,14 +138,16 @@
       boolean moveTortoise = true;
       while (Binding.isBoundLabel(actual)) {
         if (tortoise == hare) {
-          throw new NoSuchBindingException("cycle detected resolving " + virtual + " binding");
+          throw new NoSuchBindingException("cycle detected resolving " + virtual + " binding",
+              binding.getLocation());
         }
 
         Label previous = actual; // For the exception.
+        Binding oldBinding = binding;
         binding = bindMap.get(actual);
         if (binding == null) {
           throw new NoSuchBindingException("no binding found for target " + previous + " (via "
-              + virtual + ")");
+              + virtual + ")", oldBinding.getLocation());
         }
         actual = binding.getActual();
         hare = actual;
@@ -174,16 +176,6 @@
     }
 
     /**
-     * This is used when a binding is invalid, either because one of the targets is malformed,
-     * refers to a package that does not exist, or creates a circular dependency.
-     */
-    public class NoSuchBindingException extends NoSuchThingException {
-      public NoSuchBindingException(String message) {
-        super(message);
-      }
-    }
-
-    /**
      * Creates an external repository rule.
      * @throws SyntaxException if the repository name is invalid.
      */
@@ -198,5 +190,22 @@
       repositoryMap.put(RepositoryName.create("@" + rule.getName()), rule);
       return this;
     }
+
+    /**
+     * This is used when a binding is invalid, either because one of the targets is malformed,
+     * refers to a package that does not exist, or creates a circular dependency.
+     */
+    public class NoSuchBindingException extends NoSuchThingException {
+      private Location location;
+
+      public NoSuchBindingException(String message, Location location) {
+        super(message);
+        this.location = location;
+      }
+
+      public Location getLocation() {
+        return location;
+      }
+    }
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java
index a5bbbef..0e58d3f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java
@@ -89,7 +89,8 @@
     try {
       builder.resolveBindTargets(packageFactory.getRuleClass(BIND));
     } catch (NoSuchBindingException e) {
-      throw new WorkspaceFileFunctionException(e);
+      throw new WorkspaceFileFunctionException(
+          new EvalException(e.getLocation(), e.getMessage()));
     } catch (EvalException e) {
       throw new WorkspaceFileFunctionException(e);
     }