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 33df956a2aa..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 @@ -19,7 +19,50 @@ 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 + val fileName = "./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift" + + 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, _ 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") + } + } + } + } + } + } + + override fun renderOperationError(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { val operationErrorName = "${op.toUpperCamelCase()}OutputError" val rootNamespace = ctx.settings.moduleName val httpBindingSymbol = Symbol.builder() @@ -28,33 +71,52 @@ class AWSJsonHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGenerat .build() ctx.delegator.useShapeWriter(httpBindingSymbol) { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.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 + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) + + 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") - 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( + "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") + + 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 + .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 81b086fa31d..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 @@ -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 @@ -18,7 +19,49 @@ 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) { + 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(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") + } + } + } + } + } + } + + override fun renderOperationError(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { val operationErrorName = "${op.toUpperCamelCase()}OutputError" val rootNamespace = ctx.settings.moduleName val httpBindingSymbol = Symbol.builder() @@ -27,25 +70,48 @@ class AWSEc2QueryHttpResponseBindingErrorGenerator : HttpResponseBindingErrorGen .build() ctx.delegator.useShapeWriter(httpBindingSymbol) { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.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 + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) + + openBlock( + "public enum \$L: \$N {", + "}", + operationErrorName, + ClientRuntimeTypes.Http.HttpResponseErrorBinding ) { - writer.write("let ec2QueryError = try await Ec2QueryError(httpResponse: httpResponse)") - 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( + "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)") + + 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 + .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 d4d442e4e3b..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 @@ -17,9 +17,53 @@ 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 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 + val fileName = "./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift" + + 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, _ 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") + } + } + } + } + } + } + + override fun renderOperationError(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, unknownServiceErrorSymbol: Symbol) { val operationErrorName = "${op.toUpperCamelCase()}OutputError" val rootNamespace = ctx.settings.moduleName val httpBindingSymbol = Symbol.builder() @@ -28,30 +72,52 @@ class AWSRestJson1HttpResponseBindingErrorGeneratable : HttpResponseBindingError .build() ctx.delegator.useShapeWriter(httpBindingSymbol) { writer -> - writer.addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) - writer.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 + with(writer) { + addImport(AWSSwiftDependency.AWS_CLIENT_RUNTIME.target) + addImport(SwiftDependency.CLIENT_RUNTIME.target) + + 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") - 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( + "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") + + 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 + .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 04693a9187f..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 @@ -21,10 +21,52 @@ 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 + val fileName = "./$rootNamespace/models/$serviceName+ServiceErrorHelperMethod.swift" + + 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.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") + } + } + } + } + } + } 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() @@ -33,32 +75,55 @@ 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 - ) - writer.declareSection(RestXMLResponseBindingSectionId, context) { - writer.write("let restXMLError = try await \$N(httpResponse: httpResponse)", AWSClientRuntimeTypes.RestXML.RestXMLError) - 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( + "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 + ) + + declareSection(RestXMLResponseBindingSectionId, context) { + write( + "let restXMLError = try await \$N(httpResponse: httpResponse)", + AWSClientRuntimeTypes.RestXML.RestXMLError + ) + + 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) + 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/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..2005035ac74 --- /dev/null +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSJsonHttpResponseBindingErrorGeneratorTests.kt @@ -0,0 +1,74 @@ +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) + + 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 new file mode 100644 index 00000000000..9a72dce69f1 --- /dev/null +++ b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/awsrestjson/AWSRestJson1HttpResponseBindingErrorGeneratableTests.kt @@ -0,0 +1,72 @@ +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) + + 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/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/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt b/codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt index af5bdaa3bb5..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 @@ -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,13 +98,34 @@ 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) - 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 597d37b0bf1..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 @@ -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 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) case "InvalidGreeting": return try await InvalidGreeting(httpResponse: httpResponse, decoder: decoder, message: restXMLError.message, requestID: restXMLError.requestId) @@ -134,12 +136,33 @@ 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) - 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 } 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