From 042e0046620d5b491952d28bb2b10cc2175e06ab Mon Sep 17 00:00:00 2001 From: Anastasiia Dudarenko Date: Wed, 26 Nov 2025 13:54:42 +0000 Subject: [PATCH 1/2] update grpc-java version; handle StatusException error --- .../transport/grpc/GrpcErrorMapper.java | 10 ++--- .../client/transport/grpc/GrpcTransport.java | 17 ++++---- pom.xml | 2 +- .../main/java/io/a2a/grpc/A2AServiceGrpc.java | 39 +++++++++---------- 4 files changed, 33 insertions(+), 35 deletions(-) diff --git a/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcErrorMapper.java b/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcErrorMapper.java index 5f0db8f0f..290adabd3 100644 --- a/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcErrorMapper.java +++ b/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcErrorMapper.java @@ -13,20 +13,20 @@ import io.a2a.spec.TaskNotFoundError; import io.a2a.spec.UnsupportedOperationError; import io.grpc.Status; -import io.grpc.StatusRuntimeException; /** * Utility class to map gRPC StatusRuntimeException to appropriate A2A error types */ public class GrpcErrorMapper { - public static A2AClientException mapGrpcError(StatusRuntimeException e) { + public static A2AClientException mapGrpcError(Throwable e) { return mapGrpcError(e, "gRPC error: "); } - public static A2AClientException mapGrpcError(StatusRuntimeException e, String errorPrefix) { - Status.Code code = e.getStatus().getCode(); - String description = e.getStatus().getDescription(); + public static A2AClientException mapGrpcError(Throwable e, String errorPrefix) { + Status status = Status.fromThrowable(e); + Status.Code code = status.getCode(); + String description = status.getDescription(); // Extract the actual error type from the description if possible // (using description because the same code can map to multiple errors - diff --git a/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java b/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java index 4faf40f6e..46ccda313 100644 --- a/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java +++ b/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcTransport.java @@ -48,6 +48,7 @@ import io.a2a.spec.TaskResubscriptionRequest; import io.grpc.Channel; import io.grpc.Metadata; +import io.grpc.StatusException; import io.grpc.StatusRuntimeException; import io.grpc.stub.MetadataUtils; import io.grpc.stub.StreamObserver; @@ -97,7 +98,7 @@ public EventKind sendMessage(MessageSendParams request, @Nullable ClientCallCont } else { throw new A2AClientException("Server response did not contain a message or task"); } - } catch (StatusRuntimeException e) { + } catch (StatusRuntimeException | StatusException e) { throw GrpcErrorMapper.mapGrpcError(e, "Failed to send message: "); } } @@ -134,7 +135,7 @@ public Task getTask(TaskQueryParams request, @Nullable ClientCallContext context try { A2AServiceBlockingV2Stub stubWithMetadata = createBlockingStubWithMetadata(context, payloadAndHeaders); return FromProto.task(stubWithMetadata.getTask(getTaskRequest)); - } catch (StatusRuntimeException e) { + } catch (StatusRuntimeException | StatusException e) { throw GrpcErrorMapper.mapGrpcError(e, "Failed to get task: "); } } @@ -152,7 +153,7 @@ public Task cancelTask(TaskIdParams request, @Nullable ClientCallContext context try { A2AServiceBlockingV2Stub stubWithMetadata = createBlockingStubWithMetadata(context, payloadAndHeaders); return FromProto.task(stubWithMetadata.cancelTask(cancelTaskRequest)); - } catch (StatusRuntimeException e) { + } catch (StatusRuntimeException | StatusException e) { throw GrpcErrorMapper.mapGrpcError(e, "Failed to cancel task: "); } } @@ -197,7 +198,7 @@ public ListTasksResult listTasks(ListTasksParams request, @Nullable ClientCallCo grpcResponse.getTasksCount(), grpcResponse.getNextPageToken().isEmpty() ? null : grpcResponse.getNextPageToken() ); - } catch (StatusRuntimeException e) { + } catch (StatusRuntimeException | StatusException e) { throw GrpcErrorMapper.mapGrpcError(e, "Failed to list tasks: "); } } @@ -219,7 +220,7 @@ public TaskPushNotificationConfig setTaskPushNotificationConfiguration(TaskPushN try { A2AServiceBlockingV2Stub stubWithMetadata = createBlockingStubWithMetadata(context, payloadAndHeaders); return FromProto.taskPushNotificationConfig(stubWithMetadata.createTaskPushNotificationConfig(grpcRequest)); - } catch (StatusRuntimeException e) { + } catch (StatusRuntimeException | StatusException e) { throw GrpcErrorMapper.mapGrpcError(e, "Failed to create task push notification config: "); } } @@ -239,7 +240,7 @@ public TaskPushNotificationConfig getTaskPushNotificationConfiguration( try { A2AServiceBlockingV2Stub stubWithMetadata = createBlockingStubWithMetadata(context, payloadAndHeaders); return FromProto.taskPushNotificationConfig(stubWithMetadata.getTaskPushNotificationConfig(grpcRequest)); - } catch (StatusRuntimeException e) { + } catch (StatusRuntimeException | StatusException e) { throw GrpcErrorMapper.mapGrpcError(e, "Failed to get task push notification config: "); } } @@ -261,7 +262,7 @@ public List listTaskPushNotificationConfigurations( return stubWithMetadata.listTaskPushNotificationConfig(grpcRequest).getConfigsList().stream() .map(FromProto::taskPushNotificationConfig) .collect(Collectors.toList()); - } catch (StatusRuntimeException e) { + } catch (StatusRuntimeException | StatusException e) { throw GrpcErrorMapper.mapGrpcError(e, "Failed to list task push notification config: "); } } @@ -280,7 +281,7 @@ public void deleteTaskPushNotificationConfigurations(DeleteTaskPushNotificationC try { A2AServiceBlockingV2Stub stubWithMetadata = createBlockingStubWithMetadata(context, payloadAndHeaders); stubWithMetadata.deleteTaskPushNotificationConfig(grpcRequest); - } catch (StatusRuntimeException e) { + } catch (StatusRuntimeException | StatusException e) { throw GrpcErrorMapper.mapGrpcError(e, "Failed to delete task push notification config: "); } } diff --git a/pom.xml b/pom.xml index 5442bd2ac..bd7b9cd9e 100644 --- a/pom.xml +++ b/pom.xml @@ -38,7 +38,7 @@ - 1.73.0 + 1.77.0 UTF-8 3.5.0 3.14.1 diff --git a/spec-grpc/src/main/java/io/a2a/grpc/A2AServiceGrpc.java b/spec-grpc/src/main/java/io/a2a/grpc/A2AServiceGrpc.java index 3b1dbefcd..fd9e5a268 100644 --- a/spec-grpc/src/main/java/io/a2a/grpc/A2AServiceGrpc.java +++ b/spec-grpc/src/main/java/io/a2a/grpc/A2AServiceGrpc.java @@ -16,9 +16,6 @@ * - AgentCard is a static resource with only a get method. * */ -@javax.annotation.Generated( - value = "by gRPC proto compiler (version 1.73.0)", - comments = "Source: a2a.proto") @io.grpc.stub.annotations.GrpcGenerated public final class A2AServiceGrpc { @@ -773,8 +770,8 @@ protected A2AServiceBlockingV2Stub build( * task once it is completed, or a LRO if requested. * */ - public io.a2a.grpc.SendMessageResponse sendMessage(io.a2a.grpc.SendMessageRequest request) { - return io.grpc.stub.ClientCalls.blockingUnaryCall( + public io.a2a.grpc.SendMessageResponse sendMessage(io.a2a.grpc.SendMessageRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( getChannel(), getSendMessageMethod(), getCallOptions(), request); } @@ -796,8 +793,8 @@ public io.a2a.grpc.SendMessageResponse sendMessage(io.a2a.grpc.SendMessageReques * Get the current state of a task from the agent. * */ - public io.a2a.grpc.Task getTask(io.a2a.grpc.GetTaskRequest request) { - return io.grpc.stub.ClientCalls.blockingUnaryCall( + public io.a2a.grpc.Task getTask(io.a2a.grpc.GetTaskRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( getChannel(), getGetTaskMethod(), getCallOptions(), request); } @@ -806,8 +803,8 @@ public io.a2a.grpc.Task getTask(io.a2a.grpc.GetTaskRequest request) { * List tasks with optional filtering and pagination. * */ - public io.a2a.grpc.ListTasksResponse listTasks(io.a2a.grpc.ListTasksRequest request) { - return io.grpc.stub.ClientCalls.blockingUnaryCall( + public io.a2a.grpc.ListTasksResponse listTasks(io.a2a.grpc.ListTasksRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( getChannel(), getListTasksMethod(), getCallOptions(), request); } @@ -817,8 +814,8 @@ public io.a2a.grpc.ListTasksResponse listTasks(io.a2a.grpc.ListTasksRequest requ * more task updates for the task. * */ - public io.a2a.grpc.Task cancelTask(io.a2a.grpc.CancelTaskRequest request) { - return io.grpc.stub.ClientCalls.blockingUnaryCall( + public io.a2a.grpc.Task cancelTask(io.a2a.grpc.CancelTaskRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( getChannel(), getCancelTaskMethod(), getCallOptions(), request); } @@ -842,8 +839,8 @@ public io.a2a.grpc.Task cancelTask(io.a2a.grpc.CancelTaskRequest request) { * Set a push notification config for a task. * */ - public io.a2a.grpc.TaskPushNotificationConfig createTaskPushNotificationConfig(io.a2a.grpc.CreateTaskPushNotificationConfigRequest request) { - return io.grpc.stub.ClientCalls.blockingUnaryCall( + public io.a2a.grpc.TaskPushNotificationConfig createTaskPushNotificationConfig(io.a2a.grpc.CreateTaskPushNotificationConfigRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( getChannel(), getCreateTaskPushNotificationConfigMethod(), getCallOptions(), request); } @@ -852,8 +849,8 @@ public io.a2a.grpc.TaskPushNotificationConfig createTaskPushNotificationConfig(i * Get a push notification config for a task. * */ - public io.a2a.grpc.TaskPushNotificationConfig getTaskPushNotificationConfig(io.a2a.grpc.GetTaskPushNotificationConfigRequest request) { - return io.grpc.stub.ClientCalls.blockingUnaryCall( + public io.a2a.grpc.TaskPushNotificationConfig getTaskPushNotificationConfig(io.a2a.grpc.GetTaskPushNotificationConfigRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( getChannel(), getGetTaskPushNotificationConfigMethod(), getCallOptions(), request); } @@ -862,8 +859,8 @@ public io.a2a.grpc.TaskPushNotificationConfig getTaskPushNotificationConfig(io.a * Get a list of push notifications configured for a task. * */ - public io.a2a.grpc.ListTaskPushNotificationConfigResponse listTaskPushNotificationConfig(io.a2a.grpc.ListTaskPushNotificationConfigRequest request) { - return io.grpc.stub.ClientCalls.blockingUnaryCall( + public io.a2a.grpc.ListTaskPushNotificationConfigResponse listTaskPushNotificationConfig(io.a2a.grpc.ListTaskPushNotificationConfigRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( getChannel(), getListTaskPushNotificationConfigMethod(), getCallOptions(), request); } @@ -872,8 +869,8 @@ public io.a2a.grpc.ListTaskPushNotificationConfigResponse listTaskPushNotificati * GetAgentCard returns the agent card for the agent. * */ - public io.a2a.grpc.AgentCard getAgentCard(io.a2a.grpc.GetAgentCardRequest request) { - return io.grpc.stub.ClientCalls.blockingUnaryCall( + public io.a2a.grpc.AgentCard getAgentCard(io.a2a.grpc.GetAgentCardRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( getChannel(), getGetAgentCardMethod(), getCallOptions(), request); } @@ -882,8 +879,8 @@ public io.a2a.grpc.AgentCard getAgentCard(io.a2a.grpc.GetAgentCardRequest reques * Delete a push notification config for a task. * */ - public com.google.protobuf.Empty deleteTaskPushNotificationConfig(io.a2a.grpc.DeleteTaskPushNotificationConfigRequest request) { - return io.grpc.stub.ClientCalls.blockingUnaryCall( + public com.google.protobuf.Empty deleteTaskPushNotificationConfig(io.a2a.grpc.DeleteTaskPushNotificationConfigRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( getChannel(), getDeleteTaskPushNotificationConfigMethod(), getCallOptions(), request); } } From 4cb3141ee96f8aa816d04ae3ec2801dd557575c5 Mon Sep 17 00:00:00 2001 From: Anastasiia Dudarenko Date: Wed, 26 Nov 2025 16:05:10 +0000 Subject: [PATCH 2/2] Gemini code assist suggestion applied --- .../main/java/io/a2a/client/transport/grpc/GrpcErrorMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcErrorMapper.java b/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcErrorMapper.java index 290adabd3..cf245553b 100644 --- a/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcErrorMapper.java +++ b/client/transport/grpc/src/main/java/io/a2a/client/transport/grpc/GrpcErrorMapper.java @@ -15,7 +15,7 @@ import io.grpc.Status; /** - * Utility class to map gRPC StatusRuntimeException to appropriate A2A error types + * Utility class to map gRPC exceptions to appropriate A2A error types */ public class GrpcErrorMapper {