Skip to content

Commit 827230e

Browse files
Bigtable: non-functional improvements relating to error handling (#3809)
* Use gax's async error handling now that it has been upstreamed * Bigtable: non-functional improvements * Add error handling examples to the javadocs * Use gax for error handling now that the code has been upstreamed * Fix outdated bigtable-admin readme * spacing * more docs * more docs * address feedback
1 parent 64c0ee6 commit 827230e

4 files changed

Lines changed: 249 additions & 110 deletions

File tree

google-cloud-clients/google-cloud-bigtable-admin/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,23 @@ at the top of your file:
7272

7373

7474
```java
75-
import com.google.bigtable.admin.v2.ColumnFamily;
75+
import static com.google.cloud.bigtable.admin.v2.models.GCRules.GCRULES;
7676
import com.google.bigtable.admin.v2.InstanceName;
7777
import com.google.cloud.bigtable.admin.v2.BigtableTableAdminClient;
78+
import com.google.cloud.bigtable.admin.v2.models.CreateTableRequest;
79+
import com.google.cloud.bigtable.admin.v2.models.Table;
7880
```
7981

8082
Then, to create a table, use the following code:
8183
```java
8284
InstanceName instanceName = InstanceName.of("my-project", "my-instance");
8385

84-
TableAdminClient tableAdminClient = TableAdminClient.create(instanceName);
86+
BigtableTableAdminClient tableAdminClient = BigtableTableAdminClient.create(instanceName);
8587

8688
try {
87-
CreateTable createTableReq = TableAdminRequests.createTable("tableId")
89+
Table createdTable = tableAdminClient.createTable(
90+
CreateTableRequest.of("my-table")
8891
.addFamily("cf2", GCRULES.maxVersions(10));
89-
client.createTable(createTableReq);
90-
9192
} finally {
9293
tableAdminClient.close();
9394
}

google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableInstanceAdminClient.java

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.api.core.ApiFunction;
2020
import com.google.api.core.ApiFuture;
2121
import com.google.api.core.ApiFutures;
22+
import com.google.api.gax.rpc.ApiExceptions;
2223
import com.google.api.resourcenames.ResourceName;
2324
import com.google.bigtable.admin.v2.AppProfileName;
2425
import com.google.bigtable.admin.v2.ClusterName;
@@ -46,9 +47,7 @@
4647
import com.google.common.base.Verify;
4748
import com.google.common.collect.ImmutableList;
4849
import com.google.common.collect.Lists;
49-
import com.google.common.util.concurrent.Futures;
5050
import com.google.common.util.concurrent.MoreExecutors;
51-
import com.google.common.util.concurrent.UncheckedExecutionException;
5251
import com.google.iam.v1.GetIamPolicyRequest;
5352
import com.google.iam.v1.SetIamPolicyRequest;
5453
import com.google.iam.v1.TestIamPermissionsRequest;
@@ -160,7 +159,7 @@ public void close() {
160159
*/
161160
@SuppressWarnings("WeakerAccess")
162161
public Instance createInstance(CreateInstanceRequest request) {
163-
return awaitFuture(createInstanceAsync(request));
162+
return ApiExceptions.callAndTranslateApiException(createInstanceAsync(request));
164163
}
165164

166165
/**
@@ -208,7 +207,7 @@ public Instance apply(com.google.bigtable.admin.v2.Instance proto) {
208207
*/
209208
@SuppressWarnings("WeakerAccess")
210209
public Instance updateInstance(UpdateInstanceRequest request) {
211-
return awaitFuture(updateInstanceAsync(request));
210+
return ApiExceptions.callAndTranslateApiException(updateInstanceAsync(request));
212211
}
213212

214213
/**
@@ -251,7 +250,7 @@ public Instance apply(com.google.bigtable.admin.v2.Instance proto) {
251250
*/
252251
@SuppressWarnings("WeakerAccess")
253252
public Instance getInstance(String id) {
254-
return awaitFuture(getInstanceAsync(id));
253+
return ApiExceptions.callAndTranslateApiException(getInstanceAsync(id));
255254
}
256255

257256
/**
@@ -302,7 +301,7 @@ public Instance apply(com.google.bigtable.admin.v2.Instance proto) {
302301
*/
303302
@SuppressWarnings("WeakerAccess")
304303
public List<Instance> listInstances() {
305-
return awaitFuture(listInstancesAsync());
304+
return ApiExceptions.callAndTranslateApiException(listInstancesAsync());
306305
}
307306

308307
/**
@@ -385,7 +384,7 @@ public List<Instance> apply(com.google.bigtable.admin.v2.ListInstancesResponse p
385384
*/
386385
@SuppressWarnings("WeakerAccess")
387386
public void deleteInstance(String instanceId) {
388-
awaitFuture(deleteInstanceAsync(instanceId));
387+
ApiExceptions.callAndTranslateApiException(deleteInstanceAsync(instanceId));
389388
}
390389

391390
/**
@@ -434,7 +433,7 @@ public Void apply(Empty input) {
434433
*/
435434
@SuppressWarnings("WeakerAccess")
436435
public Cluster createCluster(CreateClusterRequest request) {
437-
return awaitFuture(createClusterAsync(request));
436+
return ApiExceptions.callAndTranslateApiException(createClusterAsync(request));
438437
}
439438

440439
/**
@@ -478,7 +477,7 @@ public Cluster apply(com.google.bigtable.admin.v2.Cluster proto) {
478477
*/
479478
@SuppressWarnings("WeakerAccess")
480479
public Cluster getCluster(String instanceId, String clusterId) {
481-
return awaitFuture(getClusterAsync(instanceId, clusterId));
480+
return ApiExceptions.callAndTranslateApiException(getClusterAsync(instanceId, clusterId));
482481
}
483482

484483
/**
@@ -531,7 +530,7 @@ public Cluster apply(com.google.bigtable.admin.v2.Cluster proto) {
531530
*/
532531
@SuppressWarnings("WeakerAccess")
533532
public List<Cluster> listClusters(String instanceId) {
534-
return awaitFuture(listClustersAsync(instanceId));
533+
return ApiExceptions.callAndTranslateApiException(listClustersAsync(instanceId));
535534
}
536535

537536
/**
@@ -615,7 +614,8 @@ public List<Cluster> apply(com.google.bigtable.admin.v2.ListClustersResponse pro
615614
*/
616615
@SuppressWarnings("WeakerAccess")
617616
public Cluster resizeCluster(String instanceId, String clusterId, int numServeNodes) {
618-
return awaitFuture(resizeClusterAsync(instanceId, clusterId, numServeNodes));
617+
return ApiExceptions.callAndTranslateApiException(
618+
resizeClusterAsync(instanceId, clusterId, numServeNodes));
619619
}
620620

621621
/**
@@ -662,7 +662,7 @@ public Cluster apply(com.google.bigtable.admin.v2.Cluster proto) {
662662
*/
663663
@SuppressWarnings("WeakerAccess")
664664
public void deleteCluster(String instanceId, String clusterId) {
665-
awaitFuture(deleteClusterAsync(instanceId, clusterId));
665+
ApiExceptions.callAndTranslateApiException(deleteClusterAsync(instanceId, clusterId));
666666
}
667667

668668
/**
@@ -713,7 +713,7 @@ public Void apply(Empty input) {
713713
*/
714714
@SuppressWarnings("WeakerAccess")
715715
public AppProfile createAppProfile(CreateAppProfileRequest request) {
716-
return awaitFuture(createAppProfileAsync(request));
716+
return ApiExceptions.callAndTranslateApiException(createAppProfileAsync(request));
717717
}
718718

719719
/**
@@ -759,7 +759,7 @@ public AppProfile apply(com.google.bigtable.admin.v2.AppProfile proto) {
759759
*/
760760
@SuppressWarnings("WeakerAccess")
761761
public AppProfile getAppProfile(String instanceId, String appProfileId) {
762-
return awaitFuture(getAppProfileAsync(instanceId, appProfileId));
762+
return ApiExceptions.callAndTranslateApiException(getAppProfileAsync(instanceId, appProfileId));
763763
}
764764

765765
/**
@@ -808,7 +808,7 @@ public AppProfile apply(com.google.bigtable.admin.v2.AppProfile proto) {
808808
*/
809809
@SuppressWarnings("WeakerAccess")
810810
public List<AppProfile> listAppProfiles(String instanceId) {
811-
return awaitFuture(listAppProfilesAsync(instanceId));
811+
return ApiExceptions.callAndTranslateApiException(listAppProfilesAsync(instanceId));
812812
}
813813

814814
/**
@@ -911,7 +911,7 @@ public List<AppProfile> apply(List<com.google.bigtable.admin.v2.AppProfile> inpu
911911
*/
912912
@SuppressWarnings("WeakerAccess")
913913
public AppProfile updateAppProfile(UpdateAppProfileRequest request) {
914-
return awaitFuture(updateAppProfileAsync(request));
914+
return ApiExceptions.callAndTranslateApiException(updateAppProfileAsync(request));
915915
}
916916

917917
/**
@@ -966,7 +966,7 @@ public AppProfile apply(com.google.bigtable.admin.v2.AppProfile proto) {
966966
*/
967967
@SuppressWarnings("WeakerAccess")
968968
public void deleteAppProfile(String instanceId, String appProfileId) {
969-
awaitFuture(deleteAppProfileAsync(instanceId, appProfileId));
969+
ApiExceptions.callAndTranslateApiException(deleteAppProfileAsync(instanceId, appProfileId));
970970
}
971971

972972
/**
@@ -1016,7 +1016,7 @@ public Void apply(Empty input) {
10161016
*/
10171017
@SuppressWarnings("WeakerAccess")
10181018
public Policy getIamPolicy(String instanceId) {
1019-
return awaitFuture(getIamPolicyAsync(instanceId));
1019+
return ApiExceptions.callAndTranslateApiException(getIamPolicyAsync(instanceId));
10201020
}
10211021

10221022
/**
@@ -1083,7 +1083,7 @@ public Policy apply(com.google.iam.v1.Policy proto) {
10831083
*/
10841084
@SuppressWarnings("WeakerAccess")
10851085
public Policy setIamPolicy(String instanceId, Policy policy) {
1086-
return awaitFuture(setIamPolicyAsync(instanceId, policy));
1086+
return ApiExceptions.callAndTranslateApiException(setIamPolicyAsync(instanceId, policy));
10871087
}
10881088

10891089
/**
@@ -1210,7 +1210,8 @@ public ApiFuture<List<String>> testIamPermissionAsync(String instanceId, String.
12101210
*/
12111211
@SuppressWarnings("WeakerAccess")
12121212
public List<String> testIamPermission(ResourceName resourceName, String... permissions) {
1213-
return awaitFuture(testIamPermissionAsync(resourceName, permissions));
1213+
return ApiExceptions.callAndTranslateApiException(
1214+
testIamPermissionAsync(resourceName, permissions));
12141215
}
12151216

12161217

@@ -1276,29 +1277,4 @@ public com.google.iam.v1.Policy toPb(Policy policy) {
12761277
return super.toPb(policy);
12771278
}
12781279
}
1279-
1280-
/**
1281-
* Awaits the result of a future, taking care to propagate errors while maintaining the call site
1282-
* in a suppressed exception. This allows semantic errors to be caught across threads, while
1283-
* preserving the call site in the error. The caller's stacktrace will be made available as a
1284-
* suppressed exception.
1285-
*/
1286-
// TODO(igorbernstein2): try to move this into gax
1287-
private <T> T awaitFuture(ApiFuture<T> future) {
1288-
RuntimeException error;
1289-
try {
1290-
return Futures.getUnchecked(future);
1291-
} catch (UncheckedExecutionException e) {
1292-
if (e.getCause() instanceof RuntimeException) {
1293-
error = (RuntimeException) e.getCause();
1294-
} else {
1295-
error = e;
1296-
}
1297-
} catch (RuntimeException e) {
1298-
error = e;
1299-
}
1300-
// Add the caller's stack as a suppressed exception
1301-
error.addSuppressed(new RuntimeException("Encountered error while awaiting future"));
1302-
throw error;
1303-
}
13041280
}

google-cloud-clients/google-cloud-bigtable-admin/src/main/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClient.java

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.api.core.ApiFunction;
2020
import com.google.api.core.ApiFuture;
2121
import com.google.api.core.ApiFutures;
22+
import com.google.api.gax.rpc.ApiExceptions;
2223
import com.google.bigtable.admin.v2.DeleteTableRequest;
2324
import com.google.bigtable.admin.v2.DropRowRangeRequest;
2425
import com.google.bigtable.admin.v2.GetTableRequest;
@@ -33,9 +34,7 @@
3334
import com.google.cloud.bigtable.admin.v2.stub.EnhancedBigtableTableAdminStub;
3435
import com.google.common.base.Preconditions;
3536
import com.google.common.collect.Lists;
36-
import com.google.common.util.concurrent.Futures;
3737
import com.google.common.util.concurrent.MoreExecutors;
38-
import com.google.common.util.concurrent.UncheckedExecutionException;
3938
import com.google.protobuf.ByteString;
4039
import com.google.protobuf.Empty;
4140
import java.io.IOException;
@@ -149,7 +148,7 @@ public void close() {
149148
*/
150149
@SuppressWarnings("WeakerAccess")
151150
public Table createTable(CreateTableRequest request) {
152-
return awaitFuture(createTableAsync(request));
151+
return ApiExceptions.callAndTranslateApiException(createTableAsync(request));
153152
}
154153

155154
/**
@@ -222,7 +221,7 @@ public ApiFuture<Table> createTableAsync(CreateTableRequest request) {
222221
*/
223222
@SuppressWarnings("WeakerAccess")
224223
public Table modifyFamilies(ModifyColumnFamiliesRequest request) {
225-
return awaitFuture(modifyFamiliesAsync(request));
224+
return ApiExceptions.callAndTranslateApiException(modifyFamiliesAsync(request));
226225
}
227226

228227
/**
@@ -289,7 +288,7 @@ public ApiFuture<Table> modifyFamiliesAsync(ModifyColumnFamiliesRequest request)
289288
*/
290289
@SuppressWarnings("WeakerAccess")
291290
public void deleteTable(String tableId) {
292-
awaitFuture(deleteTableAsync(tableId));
291+
ApiExceptions.callAndTranslateApiException(deleteTableAsync(tableId));
293292
}
294293

295294
/**
@@ -342,7 +341,7 @@ public ApiFuture<Void> deleteTableAsync(String tableId) {
342341
*/
343342
@SuppressWarnings("WeakerAccess")
344343
public Table getTable(String tableId) {
345-
return awaitFuture(getTableAsync(tableId));
344+
return ApiExceptions.callAndTranslateApiException(getTableAsync(tableId));
346345
}
347346

348347
/**
@@ -397,7 +396,7 @@ public ApiFuture<Table> getTableAsync(String tableId) {
397396
// TODO(igorbernstein2): consider changing this method to use relative table ids.
398397
@SuppressWarnings("WeakerAccess")
399398
public List<TableName> listTables() {
400-
return awaitFuture(listTablesAsync());
399+
return ApiExceptions.callAndTranslateApiException(listTablesAsync());
401400
}
402401

403402
/**
@@ -506,7 +505,7 @@ public List<TableName> apply(List<com.google.bigtable.admin.v2.Table> protos) {
506505
*/
507506
@SuppressWarnings("WeakerAccess")
508507
public void dropRowRange(String tableId, String rowKeyPrefix) {
509-
awaitFuture(dropRowRangeAsync(tableId, rowKeyPrefix));
508+
ApiExceptions.callAndTranslateApiException(dropRowRangeAsync(tableId, rowKeyPrefix));
510509
}
511510

512511
/**
@@ -552,7 +551,7 @@ public ApiFuture<Void> dropRowRangeAsync(String tableId, String rowKeyPrefix) {
552551
*/
553552
@SuppressWarnings("WeakerAccess")
554553
public void dropRowRange(String tableId, ByteString rowKeyPrefix) {
555-
awaitFuture(dropRowRangeAsync(tableId, rowKeyPrefix));
554+
ApiExceptions.callAndTranslateApiException(dropRowRangeAsync(tableId, rowKeyPrefix));
556555
}
557556

558557
/**
@@ -604,7 +603,7 @@ public ApiFuture<Void> dropRowRangeAsync(String tableId, ByteString rowKeyPrefix
604603
*/
605604
@SuppressWarnings("WeakerAccess")
606605
public void dropAllRows(String tableId) {
607-
awaitFuture(dropAllRowsAsync(tableId));
606+
ApiExceptions.callAndTranslateApiException(dropAllRowsAsync(tableId));
608607
}
609608

610609
/**
@@ -659,7 +658,8 @@ public ApiFuture<Void> dropAllRowsAsync(String tableId) {
659658
public void awaitReplication(String tableId) {
660659
TableName tableName = TableName
661660
.of(instanceName.getProject(), instanceName.getInstance(), tableId);
662-
awaitFuture(stub.awaitReplicationCallable().futureCall(tableName));
661+
ApiExceptions
662+
.callAndTranslateApiException(stub.awaitReplicationCallable().futureCall(tableName));
663663
}
664664

665665
/**
@@ -734,29 +734,4 @@ public Void apply(Empty empty) {
734734
},
735735
MoreExecutors.directExecutor());
736736
}
737-
738-
/**
739-
* Awaits the result of a future, taking care to propagate errors while maintaining the call site
740-
* in a suppressed exception. This allows semantic errors to be caught across threads, while
741-
* preserving the call site in the error. The caller's stacktrace will be made available as a
742-
* suppressed exception.
743-
*/
744-
// TODO(igorbernstein2): try to move this into gax
745-
private <T> T awaitFuture(ApiFuture<T> future) {
746-
RuntimeException error;
747-
try {
748-
return Futures.getUnchecked(future);
749-
} catch (UncheckedExecutionException e) {
750-
if (e.getCause() instanceof RuntimeException) {
751-
error = (RuntimeException) e.getCause();
752-
} else {
753-
error = e;
754-
}
755-
} catch (RuntimeException e) {
756-
error = e;
757-
}
758-
// Add the caller's stack as a suppressed exception
759-
error.addSuppressed(new RuntimeException("Encountered error while awaiting future"));
760-
throw error;
761-
}
762737
}

0 commit comments

Comments
 (0)