From 9a04dbd46279334bb462ec71c3ae5f8d82d034f2 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Fri, 1 Sep 2023 18:49:48 -0700 Subject: [PATCH 1/8] WIP - Initializers for service errors are not being made like initializers for operation errors are being made. --- ...WSJsonHttpResponseBindingErrorGenerator.kt | 45 ++++++++++++++++--- ...2QueryHttpResponseBindingErrorGenerator.kt | 9 +++- ...son1HttpResponseBindingErrorGeneratable.kt | 39 +++++++++++++++- ...estXMLHttpResponseBindingErrorGenerator.kt | 39 +++++++++++++++- 4 files changed, 124 insertions(+), 8 deletions(-) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt index 33df956a2aa..3f5f3c03753 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt @@ -7,6 +7,7 @@ package software.amazon.smithy.aws.swift.codegen.awsjson import software.amazon.smithy.aws.swift.codegen.AWSClientRuntimeTypes import software.amazon.smithy.aws.swift.codegen.AWSSwiftDependency +import software.amazon.smithy.aws.swift.codegen.EndpointParamsGenerator import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.StructureShape @@ -19,7 +20,40 @@ import software.amazon.smithy.swift.codegen.model.toUpperCamelCase import software.amazon.smithy.swift.codegen.utils.errorShapeName class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGeneratable { - override fun render(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { + override fun renderServiceError(ctx: ProtocolGenerator.GenerationContext) { + val serviceShape = ctx.service + val serviceName = ctx.service.id.name + val rootNamespace = ctx.settings.moduleName + + ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") {writer -> + writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + + writer.openBlock( + "func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N, _ id: String?) async throws -> \$N? {", "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.RestJSON.RestJSONError, + SwiftTypes.Error + ) { + writer.openBlock("switch error.errorType {", "}") { + val serviceErrorShapes = serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + for (errorShape in serviceErrorShapes) { + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + writer.write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id)", + errorShapeName, + errorShapeType + ) + } + writer.write("default: return nil") + } + } + } + } + + override fun renderOperationError(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { val operationErrorName = "${op.toUpperCamelCase()}OutputError" val rootNamespace = ctx.settings.moduleName val httpBindingSymbol = Symbol.builder() @@ -38,11 +72,12 @@ class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGenerat ClientRuntimeTypes.Serde.ResponseDecoder, SwiftTypes.Error ) { - writer.write( - "let restJSONError = try await \$N(httpResponse: httpResponse)", - AWSClientRuntimeTypes.RestJSON.RestJSONError - ) + writer.write("let restJSONError = try await \$N(httpResponse: httpResponse)", AWSClientRuntimeTypes.RestJSON.RestJSONError) writer.write("let requestID = httpResponse.requestId") + + writer.write("let serviceError = try await makeServiceError(httpResponse, decoder, restJSONError, requestID)") + writer.write("if let error = serviceError { return error }") + writer.openBlock("switch restJSONError.errorType {", "}") { val errorShapes = op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() for (errorShape in errorShapes) { diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt index 81b086fa31d..d88d1a57859 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt @@ -5,9 +5,11 @@ package software.amazon.smithy.aws.swift.codegen.ec2query.httpResponse +import software.amazon.smithy.aws.swift.codegen.AWSClientRuntimeTypes import software.amazon.smithy.aws.swift.codegen.AWSSwiftDependency import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.model.shapes.OperationShape +import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.StructureShape import software.amazon.smithy.swift.codegen.ClientRuntimeTypes import software.amazon.smithy.swift.codegen.SwiftDependency @@ -18,7 +20,12 @@ import software.amazon.smithy.swift.codegen.model.toUpperCamelCase import software.amazon.smithy.swift.codegen.utils.errorShapeName class AWSEc2QueryHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGeneratable { - override fun render(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { + override fun renderServiceError(ctx: ProtocolGenerator.GenerationContext) { + // No service errors in EC2 + return + } + + override fun renderOperationError(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { val operationErrorName = "${op.toUpperCamelCase()}OutputError" val rootNamespace = ctx.settings.moduleName val httpBindingSymbol = Symbol.builder() diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt index d4d442e4e3b..686bcfb07d6 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt @@ -19,7 +19,40 @@ import software.amazon.smithy.swift.codegen.model.toUpperCamelCase import software.amazon.smithy.swift.codegen.utils.errorShapeName class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingErrorGeneratable { - override fun render(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { + override fun renderServiceError(ctx: ProtocolGenerator.GenerationContext) { + val serviceShape = ctx.service + val serviceName = ctx.service.id.name + val rootNamespace = ctx.settings.moduleName + + ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") {writer -> + writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + + writer.openBlock( + "func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N, _ id: String?) async throws -> \$N? {", "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.RestJSON.RestJSONError, + SwiftTypes.Error + ) { + writer.openBlock("switch error.errorType {", "}") { + val serviceErrorShapes = serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + for (errorShape in serviceErrorShapes) { + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + writer.write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id)", + errorShapeName, + errorShapeType + ) + } + writer.write("default: return nil") + } + } + } + } + + override fun renderOperationError(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { val operationErrorName = "${op.toUpperCamelCase()}OutputError" val rootNamespace = ctx.settings.moduleName val httpBindingSymbol = Symbol.builder() @@ -40,6 +73,10 @@ class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingError ) { writer.write("let restJSONError = try await \$N(httpResponse: httpResponse)", AWSClientRuntimeTypes.RestJSON.RestJSONError) writer.write("let requestID = httpResponse.requestId") + + writer.write("let serviceError = try await makeServiceError(httpResponse, decoder, restJSONError, requestID)") + writer.write("if let error = serviceError { return error }") + writer.openBlock("switch restJSONError.errorType {", "}") { val errorShapes = op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() for (errorShape in errorShapes) { diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt index 04693a9187f..d9db2d8c1eb 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt @@ -21,10 +21,42 @@ import software.amazon.smithy.swift.codegen.model.toUpperCamelCase import software.amazon.smithy.swift.codegen.utils.errorShapeName class AWSRestXMLHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGeneratable { + override fun renderServiceError(ctx: ProtocolGenerator.GenerationContext) { + val serviceShape = ctx.service + val serviceName = ctx.service.id.name + val rootNamespace = ctx.settings.moduleName + + ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") {writer -> + writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + + writer.openBlock( + "func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N) async throws -> \$N? {", "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.RestXML.RestXMLError, + SwiftTypes.Error + ) { + writer.openBlock("switch error.errorCode {", "}") { + val serviceErrorShapes = serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + for (errorShape in serviceErrorShapes) { + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + writer.write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: restXMLError.requestId)", + errorShapeName, + errorShapeType + ) + } + writer.write("default: return nil") + } + } + } + } object RestXMLResponseBindingSectionId : SectionId - override fun render(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { + override fun renderOperationError(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { val operationErrorName = "${op.toUpperCamelCase()}OutputError" val rootNamespace = ctx.settings.moduleName val httpBindingSymbol = Symbol.builder() @@ -50,8 +82,13 @@ class AWSRestXMLHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGene "unknownServiceErrorSymbol" to unknownServiceErrorSymbol, "errorShapes" to errorShapes ) + writer.declareSection(RestXMLResponseBindingSectionId, context) { writer.write("let restXMLError = try await \$N(httpResponse: httpResponse)", AWSClientRuntimeTypes.RestXML.RestXMLError) + + writer.write("let serviceError = try await makeServiceError(httpResponse, decoder, restXMLError)") + writer.write("if let error = serviceError { return error }") + writer.openBlock("switch restXMLError.errorCode {", "}") { for (errorShape in errorShapes) { var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) From e4b15671afaa0778f1b609068d65cb5fad76abe1 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Tue, 5 Sep 2023 13:59:54 -0700 Subject: [PATCH 2/8] Add helper method for handling service errors for AWS protocols. --- .../awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt | 3 +-- .../AWSEc2QueryHttpResponseBindingErrorGenerator.kt | 2 -- .../AWSRestJson1HttpResponseBindingErrorGeneratable.kt | 2 +- .../restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt index 3f5f3c03753..41525491053 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt @@ -7,7 +7,6 @@ package software.amazon.smithy.aws.swift.codegen.awsjson import software.amazon.smithy.aws.swift.codegen.AWSClientRuntimeTypes import software.amazon.smithy.aws.swift.codegen.AWSSwiftDependency -import software.amazon.smithy.aws.swift.codegen.EndpointParamsGenerator import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.StructureShape @@ -25,7 +24,7 @@ class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGenerat val serviceName = ctx.service.id.name val rootNamespace = ctx.settings.moduleName - ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") {writer -> + ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") { writer -> writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt index d88d1a57859..c0b886cc309 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt @@ -5,11 +5,9 @@ package software.amazon.smithy.aws.swift.codegen.ec2query.httpResponse -import software.amazon.smithy.aws.swift.codegen.AWSClientRuntimeTypes import software.amazon.smithy.aws.swift.codegen.AWSSwiftDependency import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.model.shapes.OperationShape -import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.shapes.StructureShape import software.amazon.smithy.swift.codegen.ClientRuntimeTypes import software.amazon.smithy.swift.codegen.SwiftDependency diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt index 686bcfb07d6..959d120131b 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt @@ -24,7 +24,7 @@ class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingError val serviceName = ctx.service.id.name val rootNamespace = ctx.settings.moduleName - ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") {writer -> + ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") { writer -> writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt index d9db2d8c1eb..afb131851c1 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt @@ -26,7 +26,7 @@ class AWSRestXMLHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGene val serviceName = ctx.service.id.name val rootNamespace = ctx.settings.moduleName - ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") {writer -> + ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") { writer -> writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) From 6a2a453e85d239cad448f473ac7686f457dc9458 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Tue, 5 Sep 2023 14:43:29 -0700 Subject: [PATCH 3/8] Modify existing test cases. --- .../AWSEc2QueryHttpResponseBindingErrorGenerator.kt | 1 - .../customizations/Route53InvalidBatchErrorIntegrationTests.kt | 2 ++ .../restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt index c0b886cc309..333b4aa40f0 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt @@ -20,7 +20,6 @@ import software.amazon.smithy.swift.codegen.utils.errorShapeName class AWSEc2QueryHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGeneratable { override fun renderServiceError(ctx: ProtocolGenerator.GenerationContext) { // No service errors in EC2 - return } override fun renderOperationError(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt index 8ef26e48830..f539a7d9861 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt @@ -79,6 +79,8 @@ class Route53InvalidBatchErrorIntegrationTests { ) } let restXMLError = try await AWSClientRuntime.RestXMLError(httpResponse: httpResponse) + let serviceError = try await makeServiceError(httpResponse, decoder, restXMLError) + if let error = serviceError { return error } switch restXMLError.errorCode { case "InvalidChangeBatch": return try await InvalidChangeBatch(httpResponse: httpResponse, decoder: decoder, message: restXMLError.message, requestID: restXMLError.requestId) default: return try await AWSClientRuntime.UnknownAWSHTTPServiceError.makeError(httpResponse: httpResponse, message: restXMLError.message, requestID: restXMLError.requestId, typeName: restXMLError.errorCode) diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt index 597d37b0bf1..74b4ca646fa 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt @@ -25,6 +25,8 @@ class AWSRestXMLHttpResponseBindingErrorGeneratorTests { public enum GreetingWithErrorsOutputError: ClientRuntime.HttpResponseErrorBinding { public static func makeError(httpResponse: ClientRuntime.HttpResponse, decoder: ClientRuntime.ResponseDecoder? = nil) async throws -> Swift.Error { let restXMLError = try await AWSClientRuntime.RestXMLError(httpResponse: httpResponse) + let serviceError = try await makeServiceError(httpResponse, decoder, restXMLError) + if let error = serviceError { return error } switch restXMLError.errorCode { case "ComplexXMLError": return try await ComplexXMLError(httpResponse: httpResponse, decoder: decoder, message: restXMLError.message, requestID: restXMLError.requestId) case "InvalidGreeting": return try await InvalidGreeting(httpResponse: httpResponse, decoder: decoder, message: restXMLError.message, requestID: restXMLError.requestId) From 46c087966fdfdb6ba92ff2a8483d3e5b30dd6d9f Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Sun, 10 Sep 2023 13:58:51 -0700 Subject: [PATCH 4/8] Namespace helper function to ClientTypes enum and add testing for all changed protocols. --- .../swift/codegen/AWSClientRuntimeTypes.kt | 1 + ...WSJsonHttpResponseBindingErrorGenerator.kt | 41 ++++++----- ...2QueryHttpResponseBindingErrorGenerator.kt | 39 +++++++++- ...son1HttpResponseBindingErrorGeneratable.kt | 43 ++++++----- ...estXMLHttpResponseBindingErrorGenerator.kt | 41 ++++++----- .../swift/codegen/PresignerGeneratorTests.kt | 6 +- ...nHttpResponseBindingErrorGeneratorTests.kt | 72 +++++++++++++++++++ ...ttpResponseBindingErrorGeneratableTests.kt | 70 ++++++++++++++++++ .../AWSRestJson1ProtocolGeneratorTests.kt} | 4 +- ...oute53InvalidBatchErrorIntegrationTests.kt | 2 +- ...yHttpResponseBindingErrorGeneratorTests.kt | 22 ++++++ ...LHttpResponseBindingErrorGeneratorTests.kt | 21 +++++- .../awsjson/json-error.smithy | 49 +++++++++++++ .../presignable.smithy | 0 .../awsrestjson1/restjson-error.smithy | 52 ++++++++++++++ .../ec2query/query-error.smithy | 6 ++ .../restxml/xml-errors.smithy | 7 ++ 17 files changed, 412 insertions(+), 64 deletions(-) create mode 100644 codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGeneratorTests.kt create mode 100644 codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1HttpResponseBindingErrorGeneratableTests.kt rename codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/{RestJsonProtocolGeneratorTests.kt => awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt} (97%) create mode 100644 codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsjson/json-error.smithy rename codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/{awsjson10 => awsrestjson1}/presignable.smithy (100%) create mode 100644 codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsrestjson1/restjson-error.smithy diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSClientRuntimeTypes.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSClientRuntimeTypes.kt index c12ef127380..483171b4741 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSClientRuntimeTypes.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSClientRuntimeTypes.kt @@ -12,6 +12,7 @@ object AWSClientRuntimeTypes { object EC2Query { val Ec2NarrowedResponse = runtimeSymbol("Ec2NarrowedResponse") + val Ec2QueryError = runtimeSymbol("Ec2QueryError") } object AWSJSON { val XAmzTargetMiddleware = runtimeSymbol("XAmzTargetMiddleware") diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt index 41525491053..e58f83a1f8e 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt @@ -28,25 +28,28 @@ class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGenerat writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock( - "func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N, _ id: String?) async throws -> \$N? {", "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - AWSClientRuntimeTypes.RestJSON.RestJSONError, - SwiftTypes.Error - ) { - writer.openBlock("switch error.errorType {", "}") { - val serviceErrorShapes = serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - for (errorShape in serviceErrorShapes) { - val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write( - "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id)", - errorShapeName, - errorShapeType - ) + writer.openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { + writer.openBlock( + "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N, _ id: String?) async throws -> \$N? {", "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.RestJSON.RestJSONError, + SwiftTypes.Error + ) { + writer.openBlock("switch error.errorType {", "}") { + val serviceErrorShapes = + serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + for (errorShape in serviceErrorShapes) { + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + writer.write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id)", + errorShapeName, + errorShapeType + ) + } + writer.write("default: return nil") } - writer.write("default: return nil") } } } @@ -74,7 +77,7 @@ class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGenerat writer.write("let restJSONError = try await \$N(httpResponse: httpResponse)", AWSClientRuntimeTypes.RestJSON.RestJSONError) writer.write("let requestID = httpResponse.requestId") - writer.write("let serviceError = try await makeServiceError(httpResponse, decoder, restJSONError, requestID)") + writer.write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restJSONError, requestID)") writer.write("if let error = serviceError { return error }") writer.openBlock("switch restJSONError.errorType {", "}") { diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt index 333b4aa40f0..8758bf668c5 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt @@ -5,6 +5,7 @@ package software.amazon.smithy.aws.swift.codegen.ec2query.httpResponse +import software.amazon.smithy.aws.swift.codegen.AWSClientRuntimeTypes import software.amazon.smithy.aws.swift.codegen.AWSSwiftDependency import software.amazon.smithy.codegen.core.Symbol import software.amazon.smithy.model.shapes.OperationShape @@ -19,7 +20,39 @@ import software.amazon.smithy.swift.codegen.utils.errorShapeName class AWSEc2QueryHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGeneratable { override fun renderServiceError(ctx: ProtocolGenerator.GenerationContext) { - // No service errors in EC2 + val serviceShape = ctx.service + val serviceName = ctx.service.id.name + val rootNamespace = ctx.settings.moduleName + + ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") { writer -> + writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + writer.openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { + writer.openBlock( + "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N) async throws -> \$N? {", + "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.EC2Query.Ec2QueryError, + SwiftTypes.Error + ) { + writer.openBlock("switch error.errorCode {", "}") { + val serviceErrorShapes = + serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + for (errorShape in serviceErrorShapes) { + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + writer.write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.message, requestID: error.requestId)", + errorShapeName, + errorShapeType + ) + } + writer.write("default: return nil") + } + } + } + } } override fun renderOperationError(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { @@ -42,6 +75,10 @@ class AWSEc2QueryHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGen SwiftTypes.Error ) { writer.write("let ec2QueryError = try await Ec2QueryError(httpResponse: httpResponse)") + + writer.write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, ec2QueryError)") + writer.write("if let error = serviceError { return error }") + writer.openBlock("switch ec2QueryError.errorCode {", "}") { val errorShapes = op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() for (errorShape in errorShapes) { diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt index 959d120131b..ce57ee48c49 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt @@ -17,6 +17,7 @@ import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator import software.amazon.smithy.swift.codegen.integration.httpResponse.HttpResponseBindingErrorGeneratable import software.amazon.smithy.swift.codegen.model.toUpperCamelCase import software.amazon.smithy.swift.codegen.utils.errorShapeName +import software.amazon.smithy.swift.codegen.utils.toUpperCamelCase class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingErrorGeneratable { override fun renderServiceError(ctx: ProtocolGenerator.GenerationContext) { @@ -28,25 +29,29 @@ class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingError writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock( - "func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N, _ id: String?) async throws -> \$N? {", "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - AWSClientRuntimeTypes.RestJSON.RestJSONError, - SwiftTypes.Error - ) { - writer.openBlock("switch error.errorType {", "}") { - val serviceErrorShapes = serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - for (errorShape in serviceErrorShapes) { - val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write( - "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id)", - errorShapeName, - errorShapeType - ) + writer.openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { + writer.openBlock( + "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N, _ id: String?) async throws -> \$N? {", + "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.RestJSON.RestJSONError, + SwiftTypes.Error + ) { + writer.openBlock("switch error.errorType {", "}") { + val serviceErrorShapes = + serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + for (errorShape in serviceErrorShapes) { + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + writer.write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id)", + errorShapeName, + errorShapeType + ) + } + writer.write("default: return nil") } - writer.write("default: return nil") } } } @@ -74,7 +79,7 @@ class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingError writer.write("let restJSONError = try await \$N(httpResponse: httpResponse)", AWSClientRuntimeTypes.RestJSON.RestJSONError) writer.write("let requestID = httpResponse.requestId") - writer.write("let serviceError = try await makeServiceError(httpResponse, decoder, restJSONError, requestID)") + writer.write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restJSONError, requestID)") writer.write("if let error = serviceError { return error }") writer.openBlock("switch restJSONError.errorType {", "}") { diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt index afb131851c1..e28dd0555f6 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt @@ -30,25 +30,28 @@ class AWSRestXMLHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGene writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock( - "func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N) async throws -> \$N? {", "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - AWSClientRuntimeTypes.RestXML.RestXMLError, - SwiftTypes.Error - ) { - writer.openBlock("switch error.errorCode {", "}") { - val serviceErrorShapes = serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - for (errorShape in serviceErrorShapes) { - val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write( - "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: restXMLError.requestId)", - errorShapeName, - errorShapeType - ) + writer.openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { + writer.openBlock( + "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N) async throws -> \$N? {", "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.RestXML.RestXMLError, + SwiftTypes.Error + ) { + writer.openBlock("switch error.errorCode {", "}") { + val serviceErrorShapes = + serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + for (errorShape in serviceErrorShapes) { + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + writer.write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.message, requestID: error.requestId)", + errorShapeName, + errorShapeType + ) + } + writer.write("default: return nil") } - writer.write("default: return nil") } } } @@ -86,7 +89,7 @@ class AWSRestXMLHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGene writer.declareSection(RestXMLResponseBindingSectionId, context) { writer.write("let restXMLError = try await \$N(httpResponse: httpResponse)", AWSClientRuntimeTypes.RestXML.RestXMLError) - writer.write("let serviceError = try await makeServiceError(httpResponse, decoder, restXMLError)") + writer.write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restXMLError)") writer.write("if let error = serviceError { return error }") writer.openBlock("switch restXMLError.errorCode {", "}") { diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt index 070c7b6e07f..7c9f40bca56 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/PresignerGeneratorTests.kt @@ -11,7 +11,7 @@ class PresignerGeneratorTests { @Test fun `001 presignable on getFooInput`() { - val context = setupTests("awsjson10/presignable.smithy", "smithy.swift.traits#Example") + val context = setupTests("awsrestjson1/presignable.smithy", "smithy.swift.traits#Example") val contents = TestContextGenerator.getFileContents(context.manifest, "/Example/models/GetFooInput+Presigner.swift") contents.shouldSyntacticSanityCheck() val expectedContents = @@ -68,7 +68,7 @@ class PresignerGeneratorTests { @Test fun `002 presignable on postFooInput`() { - val context = setupTests("awsjson10/presignable.smithy", "smithy.swift.traits#Example") + val context = setupTests("awsrestjson1/presignable.smithy", "smithy.swift.traits#Example") val contents = TestContextGenerator.getFileContents(context.manifest, "/Example/models/PostFooInput+Presigner.swift") contents.shouldSyntacticSanityCheck() val expectedContents = @@ -128,7 +128,7 @@ class PresignerGeneratorTests { @Test fun `003 presignable on putFooInput`() { - val context = setupTests("awsjson10/presignable.smithy", "smithy.swift.traits#Example") + val context = setupTests("awsrestjson1/presignable.smithy", "smithy.swift.traits#Example") val contents = TestContextGenerator.getFileContents(context.manifest, "/Example/models/PutFooInput+Presigner.swift") contents.shouldSyntacticSanityCheck() val expectedContents = diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGeneratorTests.kt new file mode 100644 index 00000000000..80123d05c60 --- /dev/null +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGeneratorTests.kt @@ -0,0 +1,72 @@ +package software.amazon.smithy.aws.swift.codegen.awsjson + +import io.kotest.matchers.string.shouldContainOnlyOnce +import org.junit.jupiter.api.Test +import software.amazon.smithy.aws.swift.codegen.TestContext +import software.amazon.smithy.aws.swift.codegen.TestContextGenerator +import software.amazon.smithy.aws.swift.codegen.shouldSyntacticSanityCheck +import software.amazon.smithy.aws.traits.protocols.AwsJson1_0Trait + +// The model used in the tests below uses AWS Json 1.0 as the protocol. +// However, AWSJsonHttpResponseBindingErrorGenerator.kt is used for both AWS Json 1.0 and AWS Json 1.1 protocols. +// Therefore, this file tests both versions of AWS Json, 1.0 and 1.1, for the error generation. +class AWSJsonHttpResponseBindingErrorGeneratorTests { + @Test + fun `001 GreetingWithErrorsOutputError+HttpResponseBinding`() { + val context = setupTests("awsjson/json-error.smithy", "aws.protocoltests.json10#AwsJson10") + val contents = TestContextGenerator.getFileContents( + context.manifest, + "/Example/models/GreetingWithErrorsOutputError+HttpResponseErrorBinding.swift" + ) + contents.shouldSyntacticSanityCheck() + val expectedContents = + """ + public enum GreetingWithErrorsOutputError: ClientRuntime.HttpResponseErrorBinding { + public static func makeError(httpResponse: ClientRuntime.HttpResponse, decoder: ClientRuntime.ResponseDecoder? = nil) async throws -> Swift.Error { + let restJSONError = try await AWSClientRuntime.RestJSONError(httpResponse: httpResponse) + let requestID = httpResponse.requestId + let serviceError = try await Json10ProtocolClientTypes.makeServiceError(httpResponse, decoder, restJSONError, requestID) + if let error = serviceError { return error } + switch restJSONError.errorType { + case "ComplexError": return try await ComplexError(httpResponse: httpResponse, decoder: decoder, message: restJSONError.errorMessage, requestID: requestID) + case "InvalidGreeting": return try await InvalidGreeting(httpResponse: httpResponse, decoder: decoder, message: restJSONError.errorMessage, requestID: requestID) + default: return try await AWSClientRuntime.UnknownAWSHTTPServiceError.makeError(httpResponse: httpResponse, message: restJSONError.errorMessage, requestID: requestID, typeName: restJSONError.errorType) + } + } + } + """.trimIndent() + contents.shouldContainOnlyOnce(expectedContents) + } + + @Test + fun `002 AWSJson+ServiceErrorHelperMethod AWSHttpServiceError`() { + val context = setupTests("awsjson/json-error.smithy", "aws.protocoltests.json10#AwsJson10") + val contents = TestContextGenerator.getFileContents( + context.manifest, + "/Example/models/AwsJson10+ServiceErrorHelperMethod.swift" + ) + contents.shouldSyntacticSanityCheck() + val expectedContents = + """ + extension Json10ProtocolClientTypes { + static func makeServiceError(_ httpResponse: ClientRuntime.HttpResponse, _ decoder: ClientRuntime.ResponseDecoder? = nil, _ error: AWSClientRuntime.RestJSONError, _ id: String?) async throws -> Swift.Error? { + switch error.errorType { + case "ExampleServiceError": return try await ExampleServiceError(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id) + default: return nil + } + } + } + """.trimIndent() + contents.shouldContainOnlyOnce(expectedContents) + } + + private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { + val context = TestContextGenerator.initContextFrom(smithyFile, serviceShapeId, AwsJson1_0Trait.ID) + + val generator = AwsJson1_0_ProtocolGenerator() + generator.generateDeserializers(context.ctx) + generator.generateCodableConformanceForNestedTypes(context.ctx) + context.ctx.delegator.flushWriters() + return context + } +} diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1HttpResponseBindingErrorGeneratableTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1HttpResponseBindingErrorGeneratableTests.kt new file mode 100644 index 00000000000..47fec4b957b --- /dev/null +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1HttpResponseBindingErrorGeneratableTests.kt @@ -0,0 +1,70 @@ +package software.amazon.smithy.aws.swift.codegen.awsrestjson + +import io.kotest.matchers.string.shouldContainOnlyOnce +import org.junit.jupiter.api.Test +import software.amazon.smithy.aws.swift.codegen.TestContext +import software.amazon.smithy.aws.swift.codegen.TestContextGenerator +import software.amazon.smithy.aws.swift.codegen.restjson.AWSRestJson1ProtocolGenerator +import software.amazon.smithy.aws.swift.codegen.shouldSyntacticSanityCheck +import software.amazon.smithy.aws.traits.protocols.RestJson1Trait + +class AWSRestJson1HttpResponseBindingErrorGeneratableTests { + @Test + fun `001 GreetingWithErrorsOutputError+HttpResponseBinding`() { + val context = setupTests("awsrestjson1/restjson-error.smithy", "aws.protocoltests.restjson1#RestJson1") + val contents = TestContextGenerator.getFileContents( + context.manifest, + "/Example/models/GreetingWithErrorsOutputError+HttpResponseBinding.swift" + ) + contents.shouldSyntacticSanityCheck() + val expectedContents = + """ + public enum GreetingWithErrorsOutputError: ClientRuntime.HttpResponseErrorBinding { + public static func makeError(httpResponse: ClientRuntime.HttpResponse, decoder: ClientRuntime.ResponseDecoder? = nil) async throws -> Swift.Error { + let restJSONError = try await AWSClientRuntime.RestJSONError(httpResponse: httpResponse) + let requestID = httpResponse.requestId + let serviceError = try await RestJson1ProtocolClientTypes.makeServiceError(httpResponse, decoder, restJSONError, requestID) + if let error = serviceError { return error } + switch restJSONError.errorType { + case "ComplexError": return try await ComplexError(httpResponse: httpResponse, decoder: decoder, message: restJSONError.errorMessage, requestID: requestID) + case "InvalidGreeting": return try await InvalidGreeting(httpResponse: httpResponse, decoder: decoder, message: restJSONError.errorMessage, requestID: requestID) + default: return try await AWSClientRuntime.UnknownAWSHTTPServiceError.makeError(httpResponse: httpResponse, message: restJSONError.errorMessage, requestID: requestID, typeName: restJSONError.errorType) + } + } + } + """.trimIndent() + contents.shouldContainOnlyOnce(expectedContents) + } + + @Test + fun `002 AWSJson+ServiceErrorHelperMethod AWSHttpServiceError`() { + val context = setupTests("awsrestjson1/restjson-error.smithy", "aws.protocoltests.restjson1#RestJson1") + val contents = TestContextGenerator.getFileContents( + context.manifest, + "/Example/models/RestJson1+ServiceErrorHelperMethod.swift" + ) + contents.shouldSyntacticSanityCheck() + val expectedContents = + """ + extension RestJson1ProtocolClientTypes { + static func makeServiceError(_ httpResponse: ClientRuntime.HttpResponse, _ decoder: ClientRuntime.ResponseDecoder? = nil, _ error: AWSClientRuntime.RestJSONError, _ id: String?) async throws -> Swift.Error? { + switch error.errorType { + case "ExampleServiceError": return try await ExampleServiceError(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id) + default: return nil + } + } + } + """.trimIndent() + contents.shouldContainOnlyOnce(expectedContents) + } + + private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { + val context = TestContextGenerator.initContextFrom(smithyFile, serviceShapeId, RestJson1Trait.ID) + + val generator = AWSRestJson1ProtocolGenerator() + generator.generateDeserializers(context.ctx) + generator.generateCodableConformanceForNestedTypes(context.ctx) + context.ctx.delegator.flushWriters() + return context + } +} diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/RestJsonProtocolGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt similarity index 97% rename from codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/RestJsonProtocolGeneratorTests.kt rename to codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt index 9317d2077f9..11b6f6730fe 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/RestJsonProtocolGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1ProtocolGeneratorTests.kt @@ -3,14 +3,16 @@ * SPDX-License-Identifier: Apache-2.0. */ -package software.amazon.smithy.aws.swift.codegen +package software.amazon.smithy.aws.swift.codegen.awsrestjson import io.kotest.matchers.string.shouldContainOnlyOnce import org.junit.jupiter.api.Test +import software.amazon.smithy.aws.swift.codegen.TestContext import software.amazon.smithy.aws.swift.codegen.TestContextGenerator.Companion.getClientFileContents import software.amazon.smithy.aws.swift.codegen.TestContextGenerator.Companion.getModelFileContents import software.amazon.smithy.aws.swift.codegen.TestContextGenerator.Companion.initContextFrom import software.amazon.smithy.aws.swift.codegen.restjson.AWSRestJson1ProtocolGenerator +import software.amazon.smithy.aws.swift.codegen.shouldSyntacticSanityCheck import software.amazon.smithy.aws.traits.protocols.RestJson1Trait class RestJsonProtocolGeneratorTests { diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt index f539a7d9861..07540d3f56d 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt @@ -79,7 +79,7 @@ class Route53InvalidBatchErrorIntegrationTests { ) } let restXMLError = try await AWSClientRuntime.RestXMLError(httpResponse: httpResponse) - let serviceError = try await makeServiceError(httpResponse, decoder, restXMLError) + let serviceError = try await Route53ClientTypes.makeServiceError(httpResponse, decoder, restXMLError) if let error = serviceError { return error } switch restXMLError.errorCode { case "InvalidChangeBatch": return try await InvalidChangeBatch(httpResponse: httpResponse, decoder: decoder, message: restXMLError.message, requestID: restXMLError.requestId) diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt index af5bdaa3bb5..be1207e9eaa 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt @@ -24,6 +24,8 @@ class Ec2QueryHttpResponseBindingErrorGeneratorTests { public enum GreetingWithErrorsOutputError: ClientRuntime.HttpResponseErrorBinding { public static func makeError(httpResponse: ClientRuntime.HttpResponse, decoder: ClientRuntime.ResponseDecoder? = nil) async throws -> Swift.Error { let ec2QueryError = try await Ec2QueryError(httpResponse: httpResponse) + let serviceError = try await EC2ProtocolClientTypes.makeServiceError(httpResponse, decoder, ec2QueryError) + if let error = serviceError { return error } switch ec2QueryError.errorCode { case "ComplexError": return try await ComplexError(httpResponse: httpResponse, decoder: decoder, message: ec2QueryError.message, requestID: ec2QueryError.requestId) case "InvalidGreeting": return try await InvalidGreeting(httpResponse: httpResponse, decoder: decoder, message: ec2QueryError.message, requestID: ec2QueryError.requestId) @@ -96,6 +98,26 @@ class Ec2QueryHttpResponseBindingErrorGeneratorTests { """.trimIndent() contents.shouldContainOnlyOnce(expectedContents) } + + @Test + fun `005 AwsEc2+ServiceErrorHelperMethod AWSHttpServiceError`() { + val context = setupTests("ec2query/query-error.smithy", "aws.protocoltests.ec2#AwsEc2") + val contents = TestContextGenerator.getFileContents(context.manifest, "/Example/models/AwsEc2+ServiceErrorHelperMethod.swift") + contents.shouldSyntacticSanityCheck() + val expectedContents = + """ + extension EC2ProtocolClientTypes { + static func makeServiceError(_ httpResponse: ClientRuntime.HttpResponse, _ decoder: ClientRuntime.ResponseDecoder? = nil, _ error: AWSClientRuntime.Ec2QueryError) async throws -> Swift.Error? { + switch error.errorCode { + case "ExampleServiceError": return try await ExampleServiceError(httpResponse: httpResponse, decoder: decoder, message: error.message, requestID: error.requestId) + default: return nil + } + } + } + """.trimIndent() + contents.shouldContainOnlyOnce(expectedContents) + } + private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { val context = TestContextGenerator.initContextFrom(smithyFile, serviceShapeId, Ec2QueryTrait.ID) diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt index 74b4ca646fa..06b14a248d8 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt @@ -25,7 +25,7 @@ class AWSRestXMLHttpResponseBindingErrorGeneratorTests { public enum GreetingWithErrorsOutputError: ClientRuntime.HttpResponseErrorBinding { public static func makeError(httpResponse: ClientRuntime.HttpResponse, decoder: ClientRuntime.ResponseDecoder? = nil) async throws -> Swift.Error { let restXMLError = try await AWSClientRuntime.RestXMLError(httpResponse: httpResponse) - let serviceError = try await makeServiceError(httpResponse, decoder, restXMLError) + let serviceError = try await RestXmlerrorsClientTypes.makeServiceError(httpResponse, decoder, restXMLError) if let error = serviceError { return error } switch restXMLError.errorCode { case "ComplexXMLError": return try await ComplexXMLError(httpResponse: httpResponse, decoder: decoder, message: restXMLError.message, requestID: restXMLError.requestId) @@ -136,6 +136,25 @@ class AWSRestXMLHttpResponseBindingErrorGeneratorTests { contents.shouldContainOnlyOnce(expectedContents) } + @Test + fun `006 RestXml+ServiceErrorHelperMethod AWSHttpServiceError`() { + val context = setupTests("restxml/xml-errors.smithy", "aws.protocoltests.restxml#RestXml") + val contents = getFileContents(context.manifest, "/Example/models/RestXml+ServiceErrorHelperMethod.swift") + contents.shouldSyntacticSanityCheck() + val expectedContents = + """ + extension RestXmlerrorsClientTypes { + static func makeServiceError(_ httpResponse: ClientRuntime.HttpResponse, _ decoder: ClientRuntime.ResponseDecoder? = nil, _ error: AWSClientRuntime.RestXMLError) async throws -> Swift.Error? { + switch error.errorCode { + case "ExampleServiceError": return try await ExampleServiceError(httpResponse: httpResponse, decoder: decoder, message: error.message, requestID: error.requestId) + default: return nil + } + } + } + """.trimIndent() + contents.shouldContainOnlyOnce(expectedContents) + } + private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { val context = initContextFrom(smithyFile, serviceShapeId, RestXmlTrait.ID) diff --git a/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsjson/json-error.smithy b/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsjson/json-error.smithy new file mode 100644 index 00000000000..fe4916d8422 --- /dev/null +++ b/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsjson/json-error.smithy @@ -0,0 +1,49 @@ +$version: "1.0" + +namespace aws.protocoltests.json10 + +use aws.api#service +use aws.protocols#awsJson1_0 +use smithy.test#httpRequestTests +use smithy.test#httpResponseTests + +@service(sdkId: "Json10 Protocol") +@awsJson1_0 +service AwsJson10 { + version: "2023-09-08", + operations: [ + GreetingWithErrors, + ] + errors: [ExampleServiceError] +} + +@error("client") +@httpError(403) +structure ExampleServiceError { + Message: String, +} + +operation GreetingWithErrors { + output: GreetingWithErrorsOutput, + errors: [InvalidGreeting, ComplexError] +} + +structure GreetingWithErrorsOutput { + greeting: String, +} + +@error("client") +structure InvalidGreeting { + Message: String, +} + +@error("client") +structure ComplexError { + TopLevel: String, + + Nested: ComplexNestedErrorData, +} + +structure ComplexNestedErrorData { + Foo: String, +} \ No newline at end of file diff --git a/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsjson10/presignable.smithy b/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsrestjson1/presignable.smithy similarity index 100% rename from codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsjson10/presignable.smithy rename to codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsrestjson1/presignable.smithy diff --git a/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsrestjson1/restjson-error.smithy b/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsrestjson1/restjson-error.smithy new file mode 100644 index 00000000000..014cb49a356 --- /dev/null +++ b/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/awsrestjson1/restjson-error.smithy @@ -0,0 +1,52 @@ +$version: "1.0" + +namespace aws.protocoltests.restjson1 + +use aws.api#service +use aws.protocols#restJson1 +use smithy.test#httpRequestTests +use smithy.test#httpResponseTests + +@service(sdkId: "Rest Json 1 Protocol") +@restJson1 +service RestJson1 { + version: "2023-09-08", + operations: [ + GreetingWithErrors, + ] + errors: [ExampleServiceError] +} + +@error("client") +@httpError(403) +structure ExampleServiceError { + Message: String, +} + +@http(method: "GET", uri: "/test", code: 200) +operation GreetingWithErrors { + output: GreetingWithErrorsOutput, + errors: [InvalidGreeting, ComplexError] +} + +structure GreetingWithErrorsOutput { + greeting: String, +} + +@error("client") +@httpError(404) +structure InvalidGreeting { + Message: String, +} + +@error("client") +@httpError(405) +structure ComplexError { + TopLevel: String, + + Nested: ComplexNestedErrorData, +} + +structure ComplexNestedErrorData { + Foo: String, +} \ No newline at end of file diff --git a/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/ec2query/query-error.smithy b/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/ec2query/query-error.smithy index 81d0ebd8e6d..e5481d4f6b1 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/ec2query/query-error.smithy +++ b/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/ec2query/query-error.smithy @@ -16,8 +16,14 @@ service AwsEc2 { operations: [ GreetingWithErrors, ] + errors: [ExampleServiceError] } +@error("client") +@httpError(403) +structure ExampleServiceError { + Message: String, +} operation GreetingWithErrors { output: GreetingWithErrorsOutput, diff --git a/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/restxml/xml-errors.smithy b/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/restxml/xml-errors.smithy index 4acc226984b..2e9b5a2cce7 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/restxml/xml-errors.smithy +++ b/codegen/smithy-aws-swift-codegen/src/test/resources/software.amazon.smithy.aws.swift.codegen/restxml/xml-errors.smithy @@ -14,6 +14,13 @@ service RestXml { operations: [ GreetingWithErrors, ] + errors: [ExampleServiceError] +} + +@error("client") +@httpError(403) +structure ExampleServiceError { + Message: String, } @idempotent From 45dce4e36453fc791bd58e1f216b0b7253027a94 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Mon, 11 Sep 2023 14:04:53 -0700 Subject: [PATCH 5/8] Resolve David's PR comments. --- ...WSJsonHttpResponseBindingErrorGenerator.kt | 108 ++++++++++------- ...2QueryHttpResponseBindingErrorGenerator.kt | 102 +++++++++------- ...son1HttpResponseBindingErrorGeneratable.kt | 109 ++++++++++------- ...estXMLHttpResponseBindingErrorGenerator.kt | 114 ++++++++++-------- ...nHttpResponseBindingErrorGeneratorTests.kt | 8 +- ...ttpResponseBindingErrorGeneratableTests.kt | 8 +- ...yHttpResponseBindingErrorGeneratorTests.kt | 7 +- ...LHttpResponseBindingErrorGeneratorTests.kt | 8 +- 8 files changed, 271 insertions(+), 193 deletions(-) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt index e58f83a1f8e..4653e639262 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt @@ -23,32 +23,36 @@ class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGenerat val serviceShape = ctx.service val serviceName = ctx.service.id.name val rootNamespace = ctx.settings.moduleName + val fileName = "./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift" - ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + ctx.delegator.useFileWriter(fileName) { writer -> + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { - writer.openBlock( - "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N, _ id: String?) async throws -> \$N? {", "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - AWSClientRuntimeTypes.RestJSON.RestJSONError, - SwiftTypes.Error - ) { - writer.openBlock("switch error.errorType {", "}") { - val serviceErrorShapes = - serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - for (errorShape in serviceErrorShapes) { - val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write( - "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id)", - errorShapeName, - errorShapeType - ) + openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { + openBlock( + "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N, _ id: String?) async throws -> \$N? {", + "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.RestJSON.RestJSONError, + SwiftTypes.Error + ) { + openBlock("switch error.errorType {", "}") { + val serviceErrorShapes = + serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + serviceErrorShapes.forEach { errorShape -> + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id)", + errorShapeName, + errorShapeType + ) + } + write("default: return nil") } - writer.write("default: return nil") } } } @@ -64,34 +68,48 @@ class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGenerat .build() ctx.delegator.useShapeWriter(httpBindingSymbol) { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock("public enum \$L: \$N {", "}", operationErrorName, ClientRuntimeTypes.Http.HttpResponseErrorBinding) { - writer.openBlock( - "public static func makeError(httpResponse: \$N, decoder: \$D) async throws -> \$N {", "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - SwiftTypes.Error + openBlock( + "public enum \$L: \$N {", + "}", + operationErrorName, + ClientRuntimeTypes.Http.HttpResponseErrorBinding ) { - writer.write("let restJSONError = try await \$N(httpResponse: httpResponse)", AWSClientRuntimeTypes.RestJSON.RestJSONError) - writer.write("let requestID = httpResponse.requestId") + openBlock( + "public static func makeError(httpResponse: \$N, decoder: \$D) async throws -> \$N {", "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + SwiftTypes.Error + ) { + write( + "let restJSONError = try await \$N(httpResponse: httpResponse)", + AWSClientRuntimeTypes.RestJSON.RestJSONError + ) + write("let requestID = httpResponse.requestId") - writer.write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restJSONError, requestID)") - writer.write("if let error = serviceError { return error }") + write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restJSONError, requestID)") + write("if let error = serviceError { return error }") - writer.openBlock("switch restJSONError.errorType {", "}") { - val errorShapes = op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - for (errorShape in errorShapes) { - var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write( - "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: restJSONError.errorMessage, requestID: requestID)", - errorShapeName, - errorShapeType + openBlock("switch restJSONError.errorType {", "}") { + val errorShapes = + op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + errorShapes.forEach { errorShape -> + var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: restJSONError.errorMessage, requestID: requestID)", + errorShapeName, + errorShapeType + ) + } + write( + "default: return try await \$N.makeError(httpResponse: httpResponse, message: restJSONError.errorMessage, requestID: requestID, typeName: restJSONError.errorType)", + unknownServiceErrorSymbol ) } - writer.write("default: return try await \$N.makeError(httpResponse: httpResponse, message: restJSONError.errorMessage, requestID: requestID, typeName: restJSONError.errorType)", unknownServiceErrorSymbol) } } } diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt index 8758bf668c5..b05a0b851b1 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt @@ -23,32 +23,35 @@ class AWSEc2QueryHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGen val serviceShape = ctx.service val serviceName = ctx.service.id.name val rootNamespace = ctx.settings.moduleName + val fileName = "./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift" - ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { - writer.openBlock( - "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N) async throws -> \$N? {", - "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - AWSClientRuntimeTypes.EC2Query.Ec2QueryError, - SwiftTypes.Error - ) { - writer.openBlock("switch error.errorCode {", "}") { - val serviceErrorShapes = - serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - for (errorShape in serviceErrorShapes) { - val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write( - "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.message, requestID: error.requestId)", - errorShapeName, - errorShapeType - ) + ctx.delegator.useFileWriter(fileName) { writer -> + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) + openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { + openBlock( + "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N) async throws -> \$N? {", + "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.EC2Query.Ec2QueryError, + SwiftTypes.Error + ) { + openBlock("switch error.errorCode {", "}") { + val serviceErrorShapes = + serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + serviceErrorShapes.forEach { errorShape -> + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.message, requestID: error.requestId)", + errorShapeName, + errorShapeType + ) + } + write("default: return nil") } - writer.write("default: return nil") } } } @@ -64,29 +67,44 @@ class AWSEc2QueryHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGen .build() ctx.delegator.useShapeWriter(httpBindingSymbol) { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock("public enum \$L: \$N {", "}", operationErrorName, ClientRuntimeTypes.Http.HttpResponseErrorBinding) { - writer.openBlock( - "public static func makeError(httpResponse: \$N, decoder: \$D) async throws -> \$N {", "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - SwiftTypes.Error + openBlock( + "public enum \$L: \$N {", + "}", + operationErrorName, + ClientRuntimeTypes.Http.HttpResponseErrorBinding ) { - writer.write("let ec2QueryError = try await Ec2QueryError(httpResponse: httpResponse)") + openBlock( + "public static func makeError(httpResponse: \$N, decoder: \$D) async throws -> \$N {", "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + SwiftTypes.Error + ) { + write("let ec2QueryError = try await Ec2QueryError(httpResponse: httpResponse)") - writer.write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, ec2QueryError)") - writer.write("if let error = serviceError { return error }") + write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, ec2QueryError)") + write("if let error = serviceError { return error }") - writer.openBlock("switch ec2QueryError.errorCode {", "}") { - val errorShapes = op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - for (errorShape in errorShapes) { - var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write("case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: ec2QueryError.message, requestID: ec2QueryError.requestId)", errorShapeName, errorShapeType) + openBlock("switch ec2QueryError.errorCode {", "}") { + val errorShapes = + op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + errorShapes.forEach { errorShape -> + var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: ec2QueryError.message, requestID: ec2QueryError.requestId)", + errorShapeName, + errorShapeType + ) + } + write( + "default: return try await \$N.makeError(httpResponse: httpResponse, message: ec2QueryError.message, requestID: ec2QueryError.requestId, typeName: ec2QueryError.errorCode)", + unknownServiceErrorSymbol + ) } - writer.write("default: return try await \$N.makeError(httpResponse: httpResponse, message: ec2QueryError.message, requestID: ec2QueryError.requestId, typeName: ec2QueryError.errorCode)", unknownServiceErrorSymbol) } } } diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt index ce57ee48c49..ed245a308d9 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt @@ -24,33 +24,36 @@ class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingError val serviceShape = ctx.service val serviceName = ctx.service.id.name val rootNamespace = ctx.settings.moduleName + val fileName = "./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift" - ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + ctx.delegator.useFileWriter(fileName) { writer -> + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { - writer.openBlock( - "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N, _ id: String?) async throws -> \$N? {", - "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - AWSClientRuntimeTypes.RestJSON.RestJSONError, - SwiftTypes.Error - ) { - writer.openBlock("switch error.errorType {", "}") { - val serviceErrorShapes = - serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - for (errorShape in serviceErrorShapes) { - val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write( - "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id)", - errorShapeName, - errorShapeType - ) + openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { + openBlock( + "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N, _ id: String?) async throws -> \$N? {", + "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.RestJSON.RestJSONError, + SwiftTypes.Error + ) { + openBlock("switch error.errorType {", "}") { + val serviceErrorShapes = + serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + serviceErrorShapes.forEach { errorShape -> + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.errorMessage, requestID: id)", + errorShapeName, + errorShapeType + ) + } + write("default: return nil") } - writer.write("default: return nil") } } } @@ -66,34 +69,48 @@ class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingError .build() ctx.delegator.useShapeWriter(httpBindingSymbol) { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock("public enum \$L: \$N {", "}", operationErrorName, ClientRuntimeTypes.Http.HttpResponseErrorBinding) { - writer.openBlock( - "public static func makeError(httpResponse: \$N, decoder: \$D) async throws -> \$N {", "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - SwiftTypes.Error + openBlock( + "public enum \$L: \$N {", + "}", + operationErrorName, + ClientRuntimeTypes.Http.HttpResponseErrorBinding ) { - writer.write("let restJSONError = try await \$N(httpResponse: httpResponse)", AWSClientRuntimeTypes.RestJSON.RestJSONError) - writer.write("let requestID = httpResponse.requestId") + openBlock( + "public static func makeError(httpResponse: \$N, decoder: \$D) async throws -> \$N {", "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + SwiftTypes.Error + ) { + write( + "let restJSONError = try await \$N(httpResponse: httpResponse)", + AWSClientRuntimeTypes.RestJSON.RestJSONError + ) + write("let requestID = httpResponse.requestId") - writer.write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restJSONError, requestID)") - writer.write("if let error = serviceError { return error }") + write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restJSONError, requestID)") + write("if let error = serviceError { return error }") - writer.openBlock("switch restJSONError.errorType {", "}") { - val errorShapes = op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - for (errorShape in errorShapes) { - var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write( - "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: restJSONError.errorMessage, requestID: requestID)", - errorShapeName, - errorShapeType + openBlock("switch restJSONError.errorType {", "}") { + val errorShapes = + op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + errorShapes.forEach { errorShape -> + var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: restJSONError.errorMessage, requestID: requestID)", + errorShapeName, + errorShapeType + ) + } + write( + "default: return try await \$N.makeError(httpResponse: httpResponse, message: restJSONError.errorMessage, requestID: requestID, typeName: restJSONError.errorType)", + unknownServiceErrorSymbol ) } - writer.write("default: return try await \$N.makeError(httpResponse: httpResponse, message: restJSONError.errorMessage, requestID: requestID, typeName: restJSONError.errorType)", unknownServiceErrorSymbol) } } } diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt index e28dd0555f6..d73124f2e82 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt @@ -25,32 +25,36 @@ class AWSRestXMLHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGene val serviceShape = ctx.service val serviceName = ctx.service.id.name val rootNamespace = ctx.settings.moduleName + val fileName = "./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift" - ctx.delegator.useFileWriter("./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift") { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + ctx.delegator.useFileWriter(fileName) { writer -> + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { - writer.openBlock( - "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N) async throws -> \$N? {", "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - AWSClientRuntimeTypes.RestXML.RestXMLError, - SwiftTypes.Error - ) { - writer.openBlock("switch error.errorCode {", "}") { - val serviceErrorShapes = - serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - for (errorShape in serviceErrorShapes) { - val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write( - "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.message, requestID: error.requestId)", - errorShapeName, - errorShapeType - ) + openBlock("extension ${ctx.symbolProvider.toSymbol(ctx.service).name}Types {", "}") { + openBlock( + "static func makeServiceError(_ httpResponse: \$N, _ decoder: \$D, _ error: \$N) async throws -> \$N? {", + "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + AWSClientRuntimeTypes.RestXML.RestXMLError, + SwiftTypes.Error + ) { + openBlock("switch error.errorCode {", "}") { + val serviceErrorShapes = + serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + serviceErrorShapes.forEach { errorShape -> + val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: error.message, requestID: error.requestId)", + errorShapeName, + errorShapeType + ) + } + write("default: return nil") } - writer.write("default: return nil") } } } @@ -68,37 +72,51 @@ class AWSRestXMLHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGene .build() ctx.delegator.useShapeWriter(httpBindingSymbol) { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.addImport(SwiftDependency.CLIENT_RUNTIME.target) + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) - writer.openBlock("public enum \$L: \$N {", "}", operationErrorName, ClientRuntimeTypes.Http.HttpResponseErrorBinding) { - writer.openBlock( - "public static func makeError(httpResponse: \$N, decoder: \$D) async throws -> \$N {", "}", - ClientRuntimeTypes.Http.HttpResponse, - ClientRuntimeTypes.Serde.ResponseDecoder, - SwiftTypes.Error + openBlock( + "public enum \$L: \$N {", + "}", + operationErrorName, + ClientRuntimeTypes.Http.HttpResponseErrorBinding ) { - val errorShapes = op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() - val context = mapOf( - "operationErrorName" to operationErrorName, - "ctx" to ctx, - "unknownServiceErrorSymbol" to unknownServiceErrorSymbol, - "errorShapes" to errorShapes - ) + openBlock( + "public static func makeError(httpResponse: \$N, decoder: \$D) async throws -> \$N {", "}", + ClientRuntimeTypes.Http.HttpResponse, + ClientRuntimeTypes.Serde.ResponseDecoder, + SwiftTypes.Error + ) { + val errorShapes = op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + val context = mapOf( + "operationErrorName" to operationErrorName, + "ctx" to ctx, + "unknownServiceErrorSymbol" to unknownServiceErrorSymbol, + "errorShapes" to errorShapes + ) - writer.declareSection(RestXMLResponseBindingSectionId, context) { - writer.write("let restXMLError = try await \$N(httpResponse: httpResponse)", AWSClientRuntimeTypes.RestXML.RestXMLError) + declareSection(RestXMLResponseBindingSectionId, context) { + write( + "let restXMLError = try await \$N(httpResponse: httpResponse)", + AWSClientRuntimeTypes.RestXML.RestXMLError + ) - writer.write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restXMLError)") - writer.write("if let error = serviceError { return error }") + write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restXMLError)") + write("if let error = serviceError { return error }") - writer.openBlock("switch restXMLError.errorCode {", "}") { - for (errorShape in errorShapes) { - var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) - var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name - writer.write("case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: restXMLError.message, requestID: restXMLError.requestId)", errorShapeName, errorShapeType) + openBlock("switch restXMLError.errorCode {", "}") { + errorShapes.forEach { errorShape -> + var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) + var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name + write( + "case \$S: return try await \$L(httpResponse: httpResponse, decoder: decoder, message: restXMLError.message, requestID: restXMLError.requestId)", + errorShapeName, + errorShapeType + ) + } + write("default: return try await \$unknownServiceErrorSymbol:N.makeError(httpResponse: httpResponse, message: restXMLError.message, requestID: restXMLError.requestId, typeName: restXMLError.errorCode)") } - writer.write("default: return try await \$unknownServiceErrorSymbol:N.makeError(httpResponse: httpResponse, message: restXMLError.message, requestID: restXMLError.requestId, typeName: restXMLError.errorCode)") } } } diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGeneratorTests.kt index 80123d05c60..2005035ac74 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGeneratorTests.kt @@ -63,9 +63,11 @@ class AWSJsonHttpResponseBindingErrorGeneratorTests { private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { val context = TestContextGenerator.initContextFrom(smithyFile, serviceShapeId, AwsJson1_0Trait.ID) - val generator = AwsJson1_0_ProtocolGenerator() - generator.generateDeserializers(context.ctx) - generator.generateCodableConformanceForNestedTypes(context.ctx) + AwsJson1_0_ProtocolGenerator().run { + generateDeserializers(context.ctx) + generateCodableConformanceForNestedTypes(context.ctx) + } + context.ctx.delegator.flushWriters() return context } diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1HttpResponseBindingErrorGeneratableTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1HttpResponseBindingErrorGeneratableTests.kt index 47fec4b957b..9a72dce69f1 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1HttpResponseBindingErrorGeneratableTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1HttpResponseBindingErrorGeneratableTests.kt @@ -61,9 +61,11 @@ class AWSRestJson1HttpResponseBindingErrorGeneratableTests { private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { val context = TestContextGenerator.initContextFrom(smithyFile, serviceShapeId, RestJson1Trait.ID) - val generator = AWSRestJson1ProtocolGenerator() - generator.generateDeserializers(context.ctx) - generator.generateCodableConformanceForNestedTypes(context.ctx) + AWSRestJson1ProtocolGenerator().run { + generateDeserializers(context.ctx) + generateCodableConformanceForNestedTypes(context.ctx) + } + context.ctx.delegator.flushWriters() return context } diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt index be1207e9eaa..c352a7ff589 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt @@ -122,9 +122,10 @@ class Ec2QueryHttpResponseBindingErrorGeneratorTests { val context = TestContextGenerator.initContextFrom(smithyFile, serviceShapeId, Ec2QueryTrait.ID) - val generator = Ec2QueryProtocolGenerator() - generator.generateDeserializers(context.ctx) - generator.generateCodableConformanceForNestedTypes(context.ctx) + Ec2QueryProtocolGenerator().run { + generateDeserializers(context.ctx) + generateCodableConformanceForNestedTypes(context.ctx) + } context.ctx.delegator.flushWriters() return context } diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt index 06b14a248d8..7b985d37ba0 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt @@ -158,9 +158,11 @@ class AWSRestXMLHttpResponseBindingErrorGeneratorTests { private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext { val context = initContextFrom(smithyFile, serviceShapeId, RestXmlTrait.ID) - val generator = RestXmlProtocolGenerator() - generator.generateDeserializers(context.ctx) - generator.generateCodableConformanceForNestedTypes(context.ctx) + RestXmlProtocolGenerator().run { + generateDeserializers(context.ctx) + generateCodableConformanceForNestedTypes(context.ctx) + } + context.ctx.delegator.flushWriters() return context } From c29dd2e62584882211a965b916636df96951ac23 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Mon, 11 Sep 2023 17:02:34 -0700 Subject: [PATCH 6/8] Resolve code style PR nits. --- .../awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt | 6 ++++-- .../AWSEc2QueryHttpResponseBindingErrorGenerator.kt | 6 ++++-- .../AWSRestJson1HttpResponseBindingErrorGeneratable.kt | 6 ++++-- .../restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt | 5 ++++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt index 4653e639262..c37c67e8eb2 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt @@ -94,8 +94,10 @@ class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGenerat write("if let error = serviceError { return error }") openBlock("switch restJSONError.errorType {", "}") { - val errorShapes = - op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + val errorShapes = op.errors + .map { ctx.model.expectShape(it) as StructureShape } + .toSet() + .sorted() errorShapes.forEach { errorShape -> var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt index b05a0b851b1..d9e4d385233 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt @@ -89,8 +89,10 @@ class AWSEc2QueryHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGen write("if let error = serviceError { return error }") openBlock("switch ec2QueryError.errorCode {", "}") { - val errorShapes = - op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + val errorShapes = op.errors + .map { ctx.model.expectShape(it) as StructureShape } + .toSet() + .sorted() errorShapes.forEach { errorShape -> var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt index ed245a308d9..d908eb78953 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt @@ -95,8 +95,10 @@ class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingError write("if let error = serviceError { return error }") openBlock("switch restJSONError.errorType {", "}") { - val errorShapes = - op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + val errorShapes = op.errors + .map { ctx.model.expectShape(it) as StructureShape } + .toSet() + .sorted() errorShapes.forEach { errorShape -> var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) var errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt index d73124f2e82..2db618a8b9c 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt @@ -88,7 +88,10 @@ class AWSRestXMLHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGene ClientRuntimeTypes.Serde.ResponseDecoder, SwiftTypes.Error ) { - val errorShapes = op.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + val errorShapes = op.errors + .map { ctx.model.expectShape(it) as StructureShape } + .toSet() + .sorted() val context = mapOf( "operationErrorName" to operationErrorName, "ctx" to ctx, From ffd60cc3dd92c79a2a7b8f8a4768ecaf9baa7840 Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Tue, 12 Sep 2023 14:21:19 -0700 Subject: [PATCH 7/8] Fix formatting. --- .../awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt | 5 ++++- .../AWSEc2QueryHttpResponseBindingErrorGenerator.kt | 5 ++++- .../AWSRestJson1HttpResponseBindingErrorGeneratable.kt | 5 ++++- .../restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt index c37c67e8eb2..13822caf750 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt @@ -41,7 +41,10 @@ class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGenerat ) { openBlock("switch error.errorType {", "}") { val serviceErrorShapes = - serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + serviceShape.errors + .map { ctx.model.expectShape(it) as StructureShape } + .toSet() + .sorted() serviceErrorShapes.forEach { errorShape -> val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt index d9e4d385233..4c9de2ff506 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt @@ -40,7 +40,10 @@ class AWSEc2QueryHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGen ) { openBlock("switch error.errorCode {", "}") { val serviceErrorShapes = - serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + serviceShape.errors + .map { ctx.model.expectShape(it) as StructureShape } + .toSet() + .sorted() serviceErrorShapes.forEach { errorShape -> val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt index d908eb78953..46d5d0d9f6c 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt @@ -42,7 +42,10 @@ class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingError ) { openBlock("switch error.errorType {", "}") { val serviceErrorShapes = - serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + serviceShape.errors + .map { ctx.model.expectShape(it) as StructureShape } + .toSet() + .sorted() serviceErrorShapes.forEach { errorShape -> val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt index 2db618a8b9c..0403faa3004 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt @@ -43,7 +43,10 @@ class AWSRestXMLHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGene ) { openBlock("switch error.errorCode {", "}") { val serviceErrorShapes = - serviceShape.errors.map { ctx.model.expectShape(it) as StructureShape }.toSet().sorted() + serviceShape.errors + .map { ctx.model.expectShape(it) as StructureShape } + .toSet() + .sorted() serviceErrorShapes.forEach { errorShape -> val errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) val errorShapeType = ctx.symbolProvider.toSymbol(errorShape).name From f1a8e4fdf450af2d0eea5a79b914f1858db37dde Mon Sep 17 00:00:00 2001 From: Sichan Yoo Date: Tue, 12 Sep 2023 17:10:18 -0700 Subject: [PATCH 8/8] Call service error handling helper within operation error handling only if service errors exist. --- .../awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt | 6 ++++-- .../AWSEc2QueryHttpResponseBindingErrorGenerator.kt | 6 ++++-- .../AWSRestJson1HttpResponseBindingErrorGeneratable.kt | 6 ++++-- .../restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt | 7 ++++--- .../Route53InvalidBatchErrorIntegrationTests.kt | 2 -- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt index 13822caf750..ded6950e678 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGenerator.kt @@ -93,8 +93,10 @@ class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGenerat ) write("let requestID = httpResponse.requestId") - write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restJSONError, requestID)") - write("if let error = serviceError { return error }") + if (ctx.service.errors.isNotEmpty()) { + write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restJSONError, requestID)") + write("if let error = serviceError { return error }") + } openBlock("switch restJSONError.errorType {", "}") { val errorShapes = op.errors diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt index 4c9de2ff506..dd9b202e79d 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorGenerator.kt @@ -88,8 +88,10 @@ class AWSEc2QueryHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGen ) { write("let ec2QueryError = try await Ec2QueryError(httpResponse: httpResponse)") - write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, ec2QueryError)") - write("if let error = serviceError { return error }") + if (ctx.service.errors.isNotEmpty()) { + write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, ec2QueryError)") + write("if let error = serviceError { return error }") + } openBlock("switch ec2QueryError.errorCode {", "}") { val errorShapes = op.errors diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt index 46d5d0d9f6c..14123a23a5e 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restjson/AWSRestJson1HttpResponseBindingErrorGeneratable.kt @@ -94,8 +94,10 @@ class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingError ) write("let requestID = httpResponse.requestId") - write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restJSONError, requestID)") - write("if let error = serviceError { return error }") + if (ctx.service.errors.isNotEmpty()) { + write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restJSONError, requestID)") + write("if let error = serviceError { return error }") + } openBlock("switch restJSONError.errorType {", "}") { val errorShapes = op.errors diff --git a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt index 0403faa3004..d60841ce049 100644 --- a/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt +++ b/codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGenerator.kt @@ -108,9 +108,10 @@ class AWSRestXMLHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGene AWSClientRuntimeTypes.RestXML.RestXMLError ) - write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restXMLError)") - write("if let error = serviceError { return error }") - + if (ctx.service.errors.isNotEmpty()) { + write("let serviceError = try await ${ctx.symbolProvider.toSymbol(ctx.service).name}Types.makeServiceError(httpResponse, decoder, restXMLError)") + write("if let error = serviceError { return error }") + } openBlock("switch restXMLError.errorCode {", "}") { errorShapes.forEach { errorShape -> var errorShapeName = errorShape.errorShapeName(ctx.symbolProvider) diff --git a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt index 07540d3f56d..8ef26e48830 100644 --- a/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/customizations/Route53InvalidBatchErrorIntegrationTests.kt @@ -79,8 +79,6 @@ class Route53InvalidBatchErrorIntegrationTests { ) } let restXMLError = try await AWSClientRuntime.RestXMLError(httpResponse: httpResponse) - let serviceError = try await Route53ClientTypes.makeServiceError(httpResponse, decoder, restXMLError) - if let error = serviceError { return error } switch restXMLError.errorCode { case "InvalidChangeBatch": return try await InvalidChangeBatch(httpResponse: httpResponse, decoder: decoder, message: restXMLError.message, requestID: restXMLError.requestId) default: return try await AWSClientRuntime.UnknownAWSHTTPServiceError.makeError(httpResponse: httpResponse, message: restXMLError.message, requestID: restXMLError.requestId, typeName: restXMLError.errorCode)