This is an automated email from the ASF dual-hosted git repository.

damccorm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git


The following commit(s) were added to refs/heads/master by this push:
     new 5c2ba441ba8 [BigQueryIO] Improve error message when BigQuery API is 
reported as not enabled (#40233)
5c2ba441ba8 is described below

commit 5c2ba441ba8eea0630442d3ebae2e63069b1f25f
Author: Chetan Ruparel <[email protected]>
AuthorDate: Mon Sep 28 17:20:44 2026 +0530

    [BigQueryIO] Improve error message when BigQuery API is reported as not 
enabled (#40233)
    
    * [BigQueryIO] Improve error message when BigQuery API is reported as not 
enabled
    
    * Fix Slf4jDoNotLogMessageOfExceptionExplicitly and Spotless formatting
    
    * Include e.getMessage() in executeWithRetries exception and add unit test
    
    ---------
    
    Co-authored-by: Chetan Ruparel <[email protected]>
---
 .../sdk/io/gcp/bigquery/BigQueryServicesImpl.java  | 34 ++++++--
 .../io/gcp/bigquery/BigQueryServicesImplTest.java  | 98 ++++++++++++++++++++++
 2 files changed, 124 insertions(+), 8 deletions(-)

diff --git 
a/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryServicesImpl.java
 
b/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryServicesImpl.java
index 3c6ee776b67..5459926f277 100644
--- 
a/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryServicesImpl.java
+++ 
b/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryServicesImpl.java
@@ -191,6 +191,15 @@ public class BigQueryServicesImpl implements 
BigQueryServices {
 
   private static final String NO_ROWS_PRESENT = "No rows present in the 
request.";
 
+  private static final String BIGQUERY_NOT_ENABLED = "has not enabled 
BigQuery";
+
+  private static final String BIGQUERY_NOT_ENABLED_GUIDANCE =
+      "Please verify that the project ID is correct and that the BigQuery API 
is enabled for the"
+          + " project at 
https://console.cloud.google.com/apis/library/bigquery.googleapis.com.";
+          + " If the BigQuery API is already enabled, check the Google Cloud 
Status Dashboard"
+          + " (https://status.cloud.google.com/) for any ongoing 
authentication or service"
+          + " outages.";
+
   protected static final Map<String, String> API_METRIC_LABEL =
       ImmutableMap.of(
           MonitoringInfoConstants.Labels.SERVICE, "BigQuery",
@@ -1058,14 +1067,17 @@ public class BigQueryServicesImpl implements 
BigQueryServices {
             if (!ApiErrorExtractor.INSTANCE.rateLimited(e)
                 && !errorInfo.getReason().equals(QUOTA_EXCEEDED)) {
               String exceptionMessage = e.getMessage();
-              if (ApiErrorExtractor.INSTANCE.badRequest(e)
-                  && exceptionMessage != null
-                  && exceptionMessage.contains(NO_ROWS_PRESENT)) {
-                LOG.error(
-                    "No rows present in the request error likely caused by 
BigQuery Insert"
-                        + " timing out. Update 
BigQueryOptions.setHTTPWriteTimeout to be longer,"
-                        + " or 0 to disable timeouts",
-                    e.getCause());
+              if (ApiErrorExtractor.INSTANCE.badRequest(e) && exceptionMessage 
!= null) {
+                if (exceptionMessage.contains(NO_ROWS_PRESENT)) {
+                  LOG.error(
+                      "No rows present in the request error likely caused by 
BigQuery Insert"
+                          + " timing out. Update 
BigQueryOptions.setHTTPWriteTimeout to be longer,"
+                          + " or 0 to disable timeouts",
+                      e.getCause());
+                } else if (exceptionMessage.contains(BIGQUERY_NOT_ENABLED)) {
+                  LOG.error(BIGQUERY_NOT_ENABLED_GUIDANCE, e);
+                  throw new IOException(exceptionMessage + " " + 
BIGQUERY_NOT_ENABLED_GUIDANCE, e);
+                }
               }
               throw e;
             }
@@ -1734,6 +1746,12 @@ public class BigQueryServicesImpl implements 
BigQueryServices {
         return request.execute();
       } catch (IOException e) {
         lastException = e;
+        if (ApiErrorExtractor.INSTANCE.badRequest(e)
+            && e.getMessage() != null
+            && e.getMessage().contains(BIGQUERY_NOT_ENABLED)) {
+          LOG.error(BIGQUERY_NOT_ENABLED_GUIDANCE, e);
+          throw new IOException(e.getMessage() + " " + 
BIGQUERY_NOT_ENABLED_GUIDANCE, e);
+        }
         if (!shouldRetry.apply(e)) {
           break;
         }
diff --git 
a/sdks/java/io/google-cloud-platform/src/test/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryServicesImplTest.java
 
b/sdks/java/io/google-cloud-platform/src/test/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryServicesImplTest.java
index 3902fb1fca3..8dd02642444 100644
--- 
a/sdks/java/io/google-cloud-platform/src/test/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryServicesImplTest.java
+++ 
b/sdks/java/io/google-cloud-platform/src/test/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryServicesImplTest.java
@@ -1523,6 +1523,104 @@ public class BigQueryServicesImplTest {
     verifyWriteMetricWasSet("project", "dataset", "table", " no rows present 
in the request. ", 1);
   }
 
+  /**
+   * Tests that {@link DatasetServiceImpl#insertAll} logs and includes 
suggested remedy when the
+   * BigQuery API is reported as not enabled for the project.
+   */
+  @Test
+  public void testInsertBigQueryNotEnabledErrorLog() throws Exception {
+    TableReference ref =
+        new 
TableReference().setProjectId("project").setDatasetId("dataset").setTableId("table");
+    List<FailsafeValueInSingleWindow<TableRow, TableRow>> rows = new 
ArrayList<>();
+    rows.add(wrapValue(new TableRow()));
+
+    setupMockResponses(
+        response -> {
+          when(response.getStatusCode()).thenReturn(400);
+          when(response.getContentType()).thenReturn(Json.MEDIA_TYPE);
+          when(response.getContent())
+              .thenReturn(
+                  toStream(
+                      errorWithReasonAndStatus(
+                          "The project project has not enabled BigQuery.", 
400)));
+        });
+
+    DatasetServiceImpl dataService =
+        new DatasetServiceImpl(bigquery, PipelineOptionsFactory.create());
+    RuntimeException e =
+        assertThrows(
+            RuntimeException.class,
+            () ->
+                dataService.insertAll(
+                    ref,
+                    rows,
+                    null,
+                    BackOffAdapter.toGcpBackOff(TEST_BACKOFF.backoff()),
+                    TEST_BACKOFF,
+                    new MockSleeper(),
+                    InsertRetryPolicy.alwaysRetry(),
+                    null,
+                    null,
+                    false,
+                    false,
+                    false,
+                    null));
+
+    assertThat(e.getCause().getMessage(), containsString("has not enabled 
BigQuery."));
+    assertThat(
+        e.getCause().getMessage(),
+        containsString(
+            "check the Google Cloud Status Dashboard 
(https://status.cloud.google.com/)"));
+
+    verifyAllResponsesAreRead();
+    expectedLogs.verifyError(
+        "check the Google Cloud Status Dashboard 
(https://status.cloud.google.com/)");
+
+    verifyWriteMetricWasSet(
+        "project", "dataset", "table", "the project project has not enabled 
bigquery.", 1);
+  }
+
+  /**
+   * Tests that {@link BigQueryServicesImpl#executeWithRetries} fails fast 
without retrying and
+   * includes both the BigQuery error and suggested remedy when the BigQuery 
API is reported as not
+   * enabled for the project.
+   */
+  @Test
+  public void testExecuteWithRetriesBigQueryNotEnabled() throws Exception {
+    setupMockResponses(
+        response -> {
+          when(response.getStatusCode()).thenReturn(400);
+          when(response.getContentType()).thenReturn(Json.MEDIA_TYPE);
+          when(response.getContent())
+              .thenReturn(
+                  toStream(
+                      errorWithReasonAndStatus(
+                          "The project projectId has not enabled BigQuery.", 
400)));
+        });
+
+    IOException e =
+        assertThrows(
+            IOException.class,
+            () ->
+                BigQueryServicesImpl.executeWithRetries(
+                    bigquery.tables().get("projectId", "datasetId", "tableId"),
+                    "Unable to get table: tableId, aborting after 9 retries.",
+                    new MockSleeper(),
+                    BackOffAdapter.toGcpBackOff(TEST_BACKOFF.backoff()),
+                    BigQueryServicesImpl.ALWAYS_RETRY));
+
+    assertThat(e.getMessage(), containsString("The project projectId has not 
enabled BigQuery."));
+    assertThat(
+        e.getMessage(),
+        containsString(
+            "check the Google Cloud Status Dashboard 
(https://status.cloud.google.com/)"));
+    assertFalse(e.getMessage().contains("aborting after 9 retries."));
+
+    verifyAllResponsesAreRead();
+    expectedLogs.verifyError(
+        "check the Google Cloud Status Dashboard 
(https://status.cloud.google.com/)");
+  }
+
   /**
    * Tests that {@link DatasetServiceImpl#insertAll} uses the supplied {@link 
InsertRetryPolicy},
    * and returns the list of rows not retried.

Reply via email to