From b8a924672c5ddf0049649ada69b9dadf0dbf2f6a Mon Sep 17 00:00:00 2001 From: Elliot Date: Mon, 20 Apr 2026 22:12:11 -0400 Subject: [PATCH] Simplify generated error unmarshalling code in json protocol based clients. --- .../bugfix-AWSSDKforJavav2-5e43973.json | 6 ++++ .../codegen/poet/client/AsyncClientClass.java | 9 +++--- .../codegen/poet/client/SyncClientClass.java | 2 ++ .../poet/client/specs/JsonProtocolSpec.java | 28 ++++++++++++------- .../poet/client/specs/ProtocolSpec.java | 4 +++ 5 files changed, 35 insertions(+), 14 deletions(-) create mode 100644 .changes/next-release/bugfix-AWSSDKforJavav2-5e43973.json diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-5e43973.json b/.changes/next-release/bugfix-AWSSDKforJavav2-5e43973.json new file mode 100644 index 000000000000..31f79365eebf --- /dev/null +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-5e43973.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "AWS SDK for Java v2", + "contributor": "apache-hb", + "description": "Simplify generated error unmarshalling code in json protocol based clients." +} diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java index 539d5df35a43..573bd6d87c48 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java @@ -172,6 +172,7 @@ protected void addAdditionalMethods(TypeSpec.Builder type) { model)); protocolSpec.createErrorResponseHandler().ifPresent(type::addMethod); protocolSpec.createEventstreamErrorResponseHandler().ifPresent(type::addMethod); + protocolSpec.errorResponseHandlerProvider(model).ifPresent(type::addMethod); } @Override @@ -331,10 +332,10 @@ protected MethodSpec.Builder operationBody(MethodSpec.Builder builder, Operation CoreMetric.class, "SERVICE_ID", model.getMetadata().getServiceId()); builder.addStatement("apiCallMetricCollector.reportMetric($T.$L, $S)", CoreMetric.class, "OPERATION_NAME", opModel.getOperationName()); - + if (opModel.hasStreamingOutput()) { ClassName responseType = poetExtensions.getModelClass(opModel.getReturnType().getReturnType()); - + builder.addStatement("$T<$T<$T, ReturnT>, $T<$T>> $N = $T.wrapWithEndOfStreamFuture($N)", Pair.class, AsyncResponseTransformer.class, @@ -344,11 +345,11 @@ protected MethodSpec.Builder operationBody(MethodSpec.Builder builder, Operation "pair", AsyncResponseTransformerUtils.class, "asyncResponseTransformer"); - + builder.addStatement("$N = $N.left()", "asyncResponseTransformer", "pair"); - + builder.addStatement("$T<$T> $N = $N.right()", CompletableFuture.class, Void.class, diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java index 5736ddbecaf5..6c92802a3bef 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/SyncClientClass.java @@ -140,6 +140,8 @@ protected void addAdditionalMethods(TypeSpec.Builder type) { type.addMethod(updateSdkClientConfigurationMethod(configurationUtils.serviceClientConfigurationBuilderClassName(), model)); type.addMethod(protocolSpec.initProtocolFactory(model)); + + protocolSpec.errorResponseHandlerProvider(model).ifPresent(type::addMethod); } private FieldSpec logger() { diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java index b9b69d9bd8a0..3dff451d7813 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java @@ -16,6 +16,7 @@ package software.amazon.awssdk.codegen.poet.client.specs; import static software.amazon.awssdk.codegen.model.intermediate.Protocol.AWS_JSON; +import static javax.lang.model.element.Modifier.PRIVATE; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; @@ -167,12 +168,18 @@ public Optional errorResponseHandler(OperationModel opModel) { String protocolFactory = protocolFactoryLiteral(model, opModel); CodeBlock.Builder builder = CodeBlock.builder(); - ParameterizedTypeName metadataMapperType = ParameterizedTypeName.get( - ClassName.get(Function.class), - ClassName.get(String.class), - ParameterizedTypeName.get(Optional.class, ExceptionMetadata.class)); - builder.add("\n$T exceptionMetadataMapper = errorCode -> {\n", metadataMapperType); + builder.add("$T<$T> errorResponseHandler = createErrorResponseHandler($L, operationMetadata, this::exceptionMetadataMapper);", + HttpResponseHandler.class, AwsServiceException.class, protocolFactory); + + return Optional.of(builder.build()); + } + + @Override + public Optional errorResponseHandlerProvider(IntermediateModel model) { + + CodeBlock.Builder builder = CodeBlock.builder(); + builder.add("if (errorCode == null) {\n"); builder.add("return $T.empty();\n", Optional.class); builder.add("}\n"); @@ -194,12 +201,13 @@ public Optional errorResponseHandler(OperationModel opModel) { builder.add("default: return $T.empty();\n", Optional.class); builder.add("}\n"); - builder.add("};\n"); - - builder.add("$T<$T> errorResponseHandler = createErrorResponseHandler($L, operationMetadata, exceptionMetadataMapper);", - HttpResponseHandler.class, AwsServiceException.class, protocolFactory); - return Optional.of(builder.build()); + MethodSpec.Builder method = MethodSpec.methodBuilder("exceptionMetadataMapper") + .addModifiers(PRIVATE) + .addParameter(String.class, "errorCode") + .addCode(builder.build()) + .returns(ParameterizedTypeName.get(Optional.class, ExceptionMetadata.class)); + return Optional.of(method.build()); } @Override diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/ProtocolSpec.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/ProtocolSpec.java index a6bfd997fba5..ad9dc73323e8 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/ProtocolSpec.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/ProtocolSpec.java @@ -51,6 +51,10 @@ public interface ProtocolSpec { Optional errorResponseHandler(OperationModel opModel); + default Optional errorResponseHandlerProvider(IntermediateModel model) { + return Optional.empty(); + } + CodeBlock executionHandler(OperationModel opModel); /**