Repository: bazelbuild/bazel
Issue: Allow module extensions to fail on a tag
Labels: type: feature request
P2
team-ExternalDeps
area-Bzlmod

### Description of the feature request:


Module extensions should be able to fail on a particular module extension tag so that the emitted stack trace points to the location at which the particular tag was created by the user.

### What underlying problem are you trying to solve with this feature?


When a user specifies an invalid module extension tag in their `MODULE.bazel` file (e.g. a version of a dependency that isn't valid) and the module extensions `fail`s due to that, the stack trace starts with the module extension implementation function. There is no way to reference the particular tag that caused the failure, which makes it unnecessarily difficult for the user to fix the issue.

### Which operating system are you running Bazel on?


Any

### What is the output of `bazel info release`?


6.0.0

### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.


_No response_

### What's the output of `git remote get-url origin; git rev-parse master; git rev-parse HEAD` ?


_No response_

### Have you found anything relevant by searching the web?

_No response_

### Any other information, logs, or outputs that you want to share?

_No response_

Issue comments:
@fmeum Is this already fixed?
@meteorcloudy Yes, it was fixed in https://github.com/bazelbuild/bazel/pull/19274.
A fix for this issue has been included in [Bazel 6.4.0 RC1](https://releases.bazel.build/6.4.0/rc1/index.html). Please test out the release candidate and report any issues as soon as possible. Thanks!

Pull request review comments:

Patch that resolved the issue:
diff --git a/src/main/java/net/starlark/java/eval/MethodLibrary.java b/src/main/java/net/starlark/java/eval/MethodLibrary.java
index 5610061162982a..be5cf11651363b 100644
--- a/src/main/java/net/starlark/java/eval/MethodLibrary.java
+++ b/src/main/java/net/starlark/java/eval/MethodLibrary.java
@@ -15,13 +15,10 @@
 package net.starlark.java.eval;
 
 import com.google.common.base.Ascii;
-import com.google.common.base.Joiner;
 import com.google.common.collect.Ordering;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Iterator;
-import java.util.List;
 import java.util.NoSuchElementException;
 import net.starlark.java.annot.Param;
 import net.starlark.java.annot.ParamType;
@@ -679,24 +676,33 @@ public StarlarkList<?> dir(Object object, StarlarkThread thread) throws EvalExce
           @Param(
               name = "args",
               doc =
-                  "A list of values, formatted with str and joined with spaces, that appear in the"
-                      + " error message."),
+                  "A list of values, formatted with debugPrint (which is equivalent to str by"
+                      + " default) and joined with spaces, that appear in the error message."),
       useStarlarkThread = true)
   public void fail(Object msg, Object attr, Tuple args, StarlarkThread thread)
       throws EvalException {
-    List<String> elems = new ArrayList<>();
+    Printer printer = new Printer();
+    boolean needSeparator = false;
+    if (attr != Starlark.NONE) {
+      printer.append("attribute ").append((String) attr).append(":");
+      needSeparator = true;
+    }
     // msg acts like a leading element of args.
     if (msg != Starlark.NONE) {
-      elems.add(Starlark.str(msg, thread.getSemantics()));
+      if (needSeparator) {
+        printer.append(" ");
+      }
+      printer.debugPrint(msg, thread.getSemantics());
+      needSeparator = true;
     }
     for (Object arg : args) {
-      elems.add(Starlark.str(arg, thread.getSemantics()));
-    }
-    String str = Joiner.on(" ").join(elems);
-    if (attr != Starlark.NONE) {
-      str = String.format("attribute %s: %s", attr, str);
+      if (needSeparator) {
+        printer.append(" ");
+      }
+      printer.debugPrint(arg, thread.getSemantics());
+      needSeparator = true;
     }
-    throw Starlark.errorf("%s", str);
+    throw Starlark.errorf("%s", printer.toString());
   }
 
   @StarlarkMethod(


Test patch: