From 3e400b95a817268492a15054052d0877c53a6fa8 Mon Sep 17 00:00:00 2001 From: Nicole Lee Date: Mon, 3 Aug 2026 15:03:37 +0000 Subject: [PATCH 1/2] test(showcase): add integration tests showing LRO drops error details --- .../v1beta1/it/ITLongRunningOperation.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITLongRunningOperation.java b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITLongRunningOperation.java index 09208861babd..693962b2166f 100644 --- a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITLongRunningOperation.java +++ b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITLongRunningOperation.java @@ -26,6 +26,12 @@ import com.google.showcase.v1beta1.WaitRequest; import com.google.showcase.v1beta1.WaitResponse; import com.google.showcase.v1beta1.it.util.TestClientInitializer; +import com.google.api.gax.rpc.ApiException; +import com.google.rpc.Code; +import com.google.rpc.Status; +import com.google.protobuf.Any; +import com.google.showcase.v1beta1.PoetryError; +import java.util.concurrent.ExecutionException; import java.util.concurrent.CancellationException; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; @@ -193,4 +199,68 @@ void testHttpJson_LROUnsuccessfulResponse_exceedsTotalTimeout_throwsDeadlineExce TestClientInitializer.AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS); } } + + @Test + void testGRPC_LROErrorResponse_dropsErrorDetails() throws Exception { + EchoClient grpcClient = TestClientInitializer.createGrpcEchoClient(); + try { + PoetryError poetryError = + PoetryError.newBuilder().setPoem("Roses are red, violets are blue").build(); + Status status = + Status.newBuilder() + .setCode(Code.ALREADY_EXISTS_VALUE) + .setMessage("The resource already exists") + .addDetails(Any.pack(poetryError)) + .build(); + WaitRequest waitRequest = + WaitRequest.newBuilder() + .setError(status) + .build(); + OperationFuture operationFuture = + grpcClient.waitOperationCallable().futureCall(waitRequest); + ExecutionException exception = + assertThrows(ExecutionException.class, operationFuture::get); + assertThat(exception.getCause()).isInstanceOf(ApiException.class); + ApiException apiException = (ApiException) exception.getCause(); + + // Current behavior: Error details are dropped during LRO error parsing + assertThat(apiException.getErrorDetails()).isNull(); + } finally { + grpcClient.close(); + grpcClient.awaitTermination( + TestClientInitializer.AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS); + } + } + + @Test + void testHttpJson_LROErrorResponse_dropsErrorDetails() throws Exception { + EchoClient httpjsonClient = TestClientInitializer.createHttpJsonEchoClient(); + try { + PoetryError poetryError = + PoetryError.newBuilder().setPoem("Roses are red, violets are blue").build(); + Status status = + Status.newBuilder() + .setCode(Code.ALREADY_EXISTS_VALUE) + .setMessage("The resource already exists") + .addDetails(Any.pack(poetryError)) + .build(); + WaitRequest waitRequest = + WaitRequest.newBuilder() + .setError(status) + .build(); + OperationFuture operationFuture = + httpjsonClient.waitOperationCallable().futureCall(waitRequest); + ExecutionException exception = + assertThrows(ExecutionException.class, operationFuture::get); + assertThat(exception.getCause()).isInstanceOf(ApiException.class); + ApiException apiException = (ApiException) exception.getCause(); + + // Current behavior: Error details are dropped during LRO error parsing + assertThat(apiException.getErrorDetails()).isNull(); + } finally { + httpjsonClient.close(); + httpjsonClient.awaitTermination( + TestClientInitializer.AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS); + } + } } From e962535e36b37ff99c741af447b064c68673059c Mon Sep 17 00:00:00 2001 From: Nicole Lee Date: Mon, 3 Aug 2026 15:25:10 +0000 Subject: [PATCH 2/2] run formatting --- .../v1beta1/it/ITLongRunningOperation.java | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITLongRunningOperation.java b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITLongRunningOperation.java index 693962b2166f..fb2dd220ada3 100644 --- a/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITLongRunningOperation.java +++ b/java-showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITLongRunningOperation.java @@ -20,19 +20,19 @@ import com.google.api.gax.longrunning.OperationFuture; import com.google.api.gax.retrying.RetrySettings; +import com.google.api.gax.rpc.ApiException; +import com.google.protobuf.Any; import com.google.protobuf.Timestamp; +import com.google.rpc.Code; +import com.google.rpc.Status; import com.google.showcase.v1beta1.EchoClient; +import com.google.showcase.v1beta1.PoetryError; import com.google.showcase.v1beta1.WaitMetadata; import com.google.showcase.v1beta1.WaitRequest; import com.google.showcase.v1beta1.WaitResponse; import com.google.showcase.v1beta1.it.util.TestClientInitializer; -import com.google.api.gax.rpc.ApiException; -import com.google.rpc.Code; -import com.google.rpc.Status; -import com.google.protobuf.Any; -import com.google.showcase.v1beta1.PoetryError; -import java.util.concurrent.ExecutionException; import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; import org.threeten.bp.Duration; @@ -212,14 +212,10 @@ void testGRPC_LROErrorResponse_dropsErrorDetails() throws Exception { .setMessage("The resource already exists") .addDetails(Any.pack(poetryError)) .build(); - WaitRequest waitRequest = - WaitRequest.newBuilder() - .setError(status) - .build(); + WaitRequest waitRequest = WaitRequest.newBuilder().setError(status).build(); OperationFuture operationFuture = grpcClient.waitOperationCallable().futureCall(waitRequest); - ExecutionException exception = - assertThrows(ExecutionException.class, operationFuture::get); + ExecutionException exception = assertThrows(ExecutionException.class, operationFuture::get); assertThat(exception.getCause()).isInstanceOf(ApiException.class); ApiException apiException = (ApiException) exception.getCause(); @@ -244,14 +240,10 @@ void testHttpJson_LROErrorResponse_dropsErrorDetails() throws Exception { .setMessage("The resource already exists") .addDetails(Any.pack(poetryError)) .build(); - WaitRequest waitRequest = - WaitRequest.newBuilder() - .setError(status) - .build(); + WaitRequest waitRequest = WaitRequest.newBuilder().setError(status).build(); OperationFuture operationFuture = httpjsonClient.waitOperationCallable().futureCall(waitRequest); - ExecutionException exception = - assertThrows(ExecutionException.class, operationFuture::get); + ExecutionException exception = assertThrows(ExecutionException.class, operationFuture::get); assertThat(exception.getCause()).isInstanceOf(ApiException.class); ApiException apiException = (ApiException) exception.getCause();