Omit redundant 'Error in fail:' prefix from Starlark fail() error messages.

Calling `fail()` in Starlark previously formatted the final error line with `Error in fail: <message>` because `fail` is a builtin function and stack trace formatting prepended `Error in <builtin>: `. Because `fail()` is the standard mechanism in Starlark for rules, macros, and extensions to raise user-facing errors (such as invalid attribute values or unsupported targets), this prefix was redundant and made user errors look like internal failures within the `fail` function itself.

Format leaf `fail()` errors using the standard `Error: ` prefix, while preserving `Error in <builtin>: ` for other builtin functions (such as `getattr()`, `struct()`, or `dict()`).

For example, when a rule implementation calls `fail("unsupported platform: %s" % ctx.attr.platform)`:

Before:
```
Traceback (most recent call last):
	File "/workspace/pkg/rules.bzl", line 5, column 9, in _impl
		fail("unsupported platform: %s" % ctx.attr.platform)
Error in fail: unsupported platform: foo
```

After:
```
Traceback (most recent call last):
	File "/workspace/pkg/rules.bzl", line 5, column 9, in _impl
		fail("unsupported platform: %s" % ctx.attr.platform)
Error: unsupported platform: foo
```

RELNOTES: Starlark `fail()` calls now format error messages with `Error: ` instead of `Error in fail: `.
Resolves https://github.com/bazelbuild/bazel/issues/21523.
PiperOrigin-RevId: 971759352
Change-Id: Idda5352f05c8d7c297261ca65e4d2906369513a8
diff --git a/src/main/java/net/starlark/java/eval/EvalException.java b/src/main/java/net/starlark/java/eval/EvalException.java
index dab368c..717bace 100644
--- a/src/main/java/net/starlark/java/eval/EvalException.java
+++ b/src/main/java/net/starlark/java/eval/EvalException.java
@@ -204,10 +204,11 @@
     int n = callstack.size(); // n > 0
     String prefix = "Error: ";
     // If the topmost frame is a built-in, don't show it.
-    // Instead just prefix the name of the built-in onto the error message.
+    // Instead just prefix the name of the built-in onto the error message,
+    // unless it is fail() where we just use "Error: ".
     StarlarkThread.CallStackEntry leaf = callstack.get(n - 1);
     if (leaf.location.equals(Location.BUILTIN)) {
-      prefix = "Error in " + leaf.name + ": ";
+      prefix = leaf.name.equals("fail") ? "Error: " : "Error in " + leaf.name + ": ";
       n--;
     }
     if (n > 0) {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/BuildInfoFileWriteActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/BuildInfoFileWriteActionTest.java
index ab9304e..dc01b1c 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/BuildInfoFileWriteActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/BuildInfoFileWriteActionTest.java
@@ -329,7 +329,7 @@
 
     assertThat(assertThrows(ActionExecutionException.class, () -> action.execute(context)))
         .hasMessageThat()
-        .contains("Error in fail: starlark error");
+        .contains("Error: starlark error");
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/buildtool/KeepGoingTest.java b/src/test/java/com/google/devtools/build/lib/buildtool/KeepGoingTest.java
index 0343697..973cc49 100644
--- a/src/test/java/com/google/devtools/build/lib/buildtool/KeepGoingTest.java
+++ b/src/test/java/com/google/devtools/build/lib/buildtool/KeepGoingTest.java
@@ -387,7 +387,7 @@
         "command succeeded, but not all targets were analyzed",
         "//analysiserror:foo",
         "//analysiserror:bar");
-    events.assertContainsError("Error in fail: BOOM!");
+    events.assertContainsError("Error: BOOM!");
 
     assertSameConfiguredTarget("//analysiserror:bar");
   }
diff --git a/src/test/java/com/google/devtools/build/lib/rules/config/StarlarkConfigFeatureFlagTransitionFactoryTest.java b/src/test/java/com/google/devtools/build/lib/rules/config/StarlarkConfigFeatureFlagTransitionFactoryTest.java
index 6b47a45..f4681fd 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/config/StarlarkConfigFeatureFlagTransitionFactoryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/config/StarlarkConfigFeatureFlagTransitionFactoryTest.java
@@ -209,7 +209,7 @@
         """);
     reporter.removeHandler(failFastHandler);
     getConfiguredTarget("//foo:top");
-    assertContainsEvent("Error in fail: Rule has failed intentionally.");
+    assertContainsEvent("Error: Rule has failed intentionally.");
   }
 
   @Test
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/EvalMacroFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/EvalMacroFunctionTest.java
index 8444ee2..3cd4dd9 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/EvalMacroFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/EvalMacroFunctionTest.java
@@ -369,7 +369,7 @@
         \t\tmy_macro = macro(implementation = _impl)
         \tFile "/workspace/pkg/my_macro.bzl", line 3, column 9, in _impl
         \t\tfail("fail fail fail")
-        Error in fail: fail fail fail\
+        Error: fail fail fail\
         """);
   }
 
@@ -510,7 +510,7 @@
         \t\tfail_macro = macro(implementation = _impl)
         \tFile "/workspace/pkg/fail_macro.bzl", line 3, column 9, in _impl
         \t\tfail("fail fail fail")
-        Error in fail: fail fail fail\
+        Error: fail fail fail\
         """,
         "cannot compute package piece for finalizer macro //pkg:finalize defined by"
             + " //pkg:my_finalizer.bzl%my_finalizer");
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
index 3277f5d..bd55ab4 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
@@ -378,7 +378,7 @@
         \t\tmy_macro = macro(implementation = _impl)
         \tFile "/workspace/pkg/my_macro.bzl", line 3, column 9, in _impl
         \t\tfail("fail fail fail")
-        Error in fail: fail fail fail\
+        Error: fail fail fail\
         """);
     if (computationMode.equals(ComputationMode.MONOLITHIC_PACKAGE)) {
       assertThat(eventCollector.filtered(EventKind.ERROR)).hasSize(1);
diff --git a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleContextTest.java b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleContextTest.java
index a9db8a9..2f54f0f 100644
--- a/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleContextTest.java
+++ b/src/test/java/com/google/devtools/build/lib/starlark/StarlarkRuleContextTest.java
@@ -3307,7 +3307,7 @@
     //
     //     /workspace/test/rules.bzl:7:15: Traceback (most recent call last):
     //          File "/workspace/test/rules.bzl", line 2, column 9, in fail_with_message
-    //     Error in fail: args expansion error message
+    //     Error: args expansion error message
     // ```
 
     // stack=[fail_with_message@rules.bzl:2, fail@<builtin>]
@@ -3315,7 +3315,7 @@
     assertThat(e)
         .hasMessageThat()
         .contains("File \"/workspace/test/rules.bzl\", line 2, column 9, in fail_with_message");
-    assertThat(e).hasMessageThat().contains("Error in fail: args expansion error message");
+    assertThat(e).hasMessageThat().contains("Error: args expansion error message");
   }
 
   @Test
diff --git a/src/test/java/net/starlark/java/eval/MethodLibraryTest.java b/src/test/java/net/starlark/java/eval/MethodLibraryTest.java
index ca9a7b1..0f0d25e 100644
--- a/src/test/java/net/starlark/java/eval/MethodLibraryTest.java
+++ b/src/test/java/net/starlark/java/eval/MethodLibraryTest.java
@@ -779,6 +779,8 @@
       customSemanticsEv.eval("fail('with_a_trace')");
     } catch (EvalException e) {
       assertThat(e.getMessageWithStack()).contains("Traceback (most recent call last)");
+      assertThat(e.getMessageWithStack()).contains("Error: with_a_trace");
+      assertThat(e.getMessageWithStack()).doesNotContain("Error in fail");
     }
 
     try {
diff --git a/src/test/py/bazel/bzlmod/mod_command_test.py b/src/test/py/bazel/bzlmod/mod_command_test.py
index 7a1755f..687ef70 100644
--- a/src/test/py/bazel/bzlmod/mod_command_test.py
+++ b/src/test/py/bazel/bzlmod/mod_command_test.py
@@ -264,7 +264,7 @@
         'ERROR: Results may be incomplete as 1 extension failed.', stderr
     )
     self.assertIn('\t\tfail("ext failed")', stderr)
-    self.assertIn('Error in fail: ext failed', stderr)
+    self.assertIn('Error: ext failed', stderr)
     self.assertListEqual(
         stdout,
         [
@@ -1430,7 +1430,7 @@
     stderr = '\n'.join(stderr)
     self.assertIn('ext1 is being evaluated', stderr)
     self.assertIn('ext2 is being evaluated', stderr)
-    self.assertIn('Error in fail: ext2 failed', stderr)
+    self.assertIn('Error: ext2 failed', stderr)
     self.assertIn(
         'Not imported, but reported as direct dependencies by the extension'
         ' (may cause the build to fail):\nmissing_dep',
diff --git a/src/test/shell/integration/build_event_stream_test.sh b/src/test/shell/integration/build_event_stream_test.sh
index 3093f17..2c7c02f 100755
--- a/src/test/shell/integration/build_event_stream_test.sh
+++ b/src/test/shell/integration/build_event_stream_test.sh
@@ -1627,7 +1627,7 @@
     >& "$TEST_log" && fail "Expected failure"
   expect_log "unsuccessful-because-of-illegal-load.*Label '//no/such/package:f.bzl' is invalid because 'no/such/package' is not a package"
   expect_log "unsuccessful-because-of-BUILD-file-syntax-error.*invalid character: '@'"
-  expect_log "Error in fail: bad"
+  expect_log "Error: bad"
 
   # On this invocation, Bazel attempts to load exactly 5 packages.
   expect_log_n "PROGRESS.*Loading package" 5