googleapis / googleapis/google-cloud-java

Compute LRO exceptions drop structured operation error details

Abierto
#13,369 0 comentarios 0 reacciones 1 asignado Reclamado por @nnicolee Ver en GitHub
Lenguaje dominante
Java
Estrellas
2.1k
Forks
1.2k
Merge medio
1 d 23 h
PR fusionados (30 d)
154

Descripción

### Description

When a Compute Engine long-running operation completes with `status: DONE` and an operation-level error, the Java client exception produced by `OperationFuture.get()` appears to keep only `httpErrorStatusCode` / `httpErrorMessage` in the exception message. Structured details under `operation.error.errors[]` are not included, which can discard the actionable provider error.

Example operation payload shape:

```text
status: DONE
error.errors[0].code: INVALID_USAGE
error.errors[0].message: No attached disk found with device name ''
httpErrorStatusCode: 400
httpErrorMessage: BAD REQUEST
```

The thrown exception message becomes similar to:

```text
com.google.api.gax.rpc.InvalidArgumentException: Operation with name "..." failed with status = HttpJsonStatusCode{statusCode=INVALID_ARGUMENT} and message = BAD REQUEST
```

The important detail `INVALID_USAGE: No attached disk found with device name ...` is not present in the exception message.

### Why this matters

For Compute operations such as `InstancesClient.detachDiskAsync(...).get()`, `BAD REQUEST` / `INVALID_ARGUMENT` is too generic for operators and applications to distinguish idempotent conditions from real invalid input. The structured operation error contains the actionable reason, but it is not surfaced by the default exception path.

### Code path observed

Current generated Compute client code seems to build the REST LRO snapshot from only the HTTP error status/message:

- `InstancesClient.detachDiskAsync(...)` calls `detachDiskOperationCallable().futureCall(request)`:
https://github.com/googleapis/google-cloud-java/blob/58e50fc35625f8364e99516235c887442f0958af/java-compute/google-cloud-compute/src/main/java/com/google/cloud/compute/v1/InstancesClient.java#L2489-L2531
- `HttpJsonInstancesStub` detach disk operation snapshot uses only `response.getHttpErrorStatusCode()` and `response.getHttpErrorMessage()`:
https://github.com/googleapis/google-cloud-java/blob/58e50fc35625f8364e99516235c887442f0958af/java-compute/google-cloud-compute/src/main/java/com/google/cloud/compute/v1/stub/HttpJsonInstancesStub.java#L671-L682
- `InstancesStubSettings` wires this into `ProtoOperationTransformers.ResponseTransformer.create(Operation.class)`:
https://github.com/googleapis/google-cloud-java/blob/58e50fc35625f8364e99516235c887442f0958af/java-compute/google-cloud-compute/src/main/java/com/google/cloud/compute/v1/stub/InstancesStubSettings.java#L2294-L2305

In gax, the response transformer creates the exception message from `operationSnapshot.getErrorCode()` and `operationSnapshot.getErrorMessage()` only:

- https://github.com/googleapis/sdk-platform-java/blob/febe86f1ea4f0b5e6d8454024ed499adb7dc9328/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ProtoOperationTransformers.java#L52-L65

HTTP 400 is then mapped to `INVALID_ARGUMENT`, and `ApiExceptionFactory` maps that to `InvalidArgumentException`:

- https://github.com/googleapis/sdk-platform-java/blob/febe86f1ea4f0b5e6d8454024ed499adb7dc9328/gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonStatusCode.java#L96-L103
- https://github.com/googleapis/sdk-platform-java/blob/febe86f1ea4f0b5e6d8454024ed499adb7dc9328/gax-java/gax/src/main/java/com/google/api/gax/rpc/ApiExceptionFactory.java#L44-L53

### Expected behavior

When the operation response contains structured error details, the thrown exception should expose or preserve them. For example, the exception message or an accessible error detail field should include something like:

```text
INVALID_USAGE: No attached disk found with device name ''
```

### Actual behavior

The default exception message only includes:

```text
status = HttpJsonStatusCode{statusCode=INVALID_ARGUMENT} and message = BAD REQUEST
```

### Possible fixes

- Include `Operation.error.errors[]` in the generated Compute `OperationSnapshot` error message, where available.
- Or preserve the original Compute `Operation` error details in the gax exception / `ErrorDetails` so callers can inspect them programmatically.
- Or provide documented guidance for retrieving the full failed operation response after `OperationFuture.get()` throws.

If this belongs in `googleapis/sdk-platform-java` instead of this generated client repo, please redirect or transfer. The generated Compute client appears to be where the Compute-specific `Operation.error.errors[]` data is first collapsed into generic HTTP status/message.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.