Skip to content

Commit 62f20cc

Browse files
authored
fix: error type of modeled service errors (#331)
1 parent 9b6f7b5 commit 62f20cc

File tree

6 files changed

+72
-13
lines changed

6 files changed

+72
-13
lines changed

codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSClientRuntimeTypes.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ object AWSClientRuntimeTypes {
2121

2222
object RestXML {
2323
val RestXMLError = runtimeSymbol("RestXMLError")
24+
val ErrorResponseContainer = runtimeSymbol("ErrorResponseContainer")
2425
}
2526

2627
object Signing {

codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/httpResponse/AWSEc2QueryHttpResponseBindingErrorInitGeneratorFactory.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
package software.amazon.smithy.aws.swift.codegen.ec2query.httpResponse
77

8-
import software.amazon.smithy.codegen.core.Symbol
98
import software.amazon.smithy.model.shapes.StructureShape
109
import software.amazon.smithy.model.traits.TimestampFormatTrait
1110
import software.amazon.smithy.swift.codegen.SwiftWriter
@@ -24,14 +23,12 @@ class AWSEc2QueryHttpResponseBindingErrorInitGeneratorFactory : HttpResponseBind
2423
ctx: ProtocolGenerator.GenerationContext,
2524
structureShape: StructureShape,
2625
httpBindingResolver: HttpBindingResolver,
27-
serviceErrorProtocolSymbol: Symbol,
2826
defaultTimestampFormat: TimestampFormatTrait.Format,
2927
): HttpResponseBindingRenderable {
3028
return HttpResponseBindingErrorInitGenerator(
3129
ctx,
3230
structureShape,
3331
httpBindingResolver,
34-
serviceErrorProtocolSymbol,
3532
defaultTimestampFormat,
3633
AWSEc2QueryHttpResponseTraitPayloadFactory()
3734
)

codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/httpResponse/AWSXMLHttpResponseBindingErrorInitGeneratorFactory.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
package software.amazon.smithy.aws.swift.codegen.restxml
77

88
import software.amazon.smithy.aws.swift.codegen.restxml.httpResponse.AWSXMLHttpResponseTraitWithoutPayload
9-
import software.amazon.smithy.codegen.core.Symbol
109
import software.amazon.smithy.model.shapes.StructureShape
1110
import software.amazon.smithy.model.traits.TimestampFormatTrait
1211
import software.amazon.smithy.swift.codegen.SwiftWriter
@@ -25,14 +24,12 @@ class AWSXMLHttpResponseBindingErrorInitGeneratorFactory : HttpResponseBindingEr
2524
ctx: ProtocolGenerator.GenerationContext,
2625
structureShape: StructureShape,
2726
httpBindingResolver: HttpBindingResolver,
28-
serviceErrorProtocolSymbol: Symbol,
2927
defaultTimestampFormat: TimestampFormatTrait.Format,
3028
): HttpResponseBindingRenderable {
3129
return HttpResponseBindingErrorInitGenerator(
3230
ctx,
3331
structureShape,
3432
httpBindingResolver,
35-
serviceErrorProtocolSymbol,
3633
defaultTimestampFormat,
3734
AWSXMLHttpResponseTraitPayloadFactory()
3835
)

codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/httpResponse/AWSXMLHttpResponseTraitWithoutPayload.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package software.amazon.smithy.aws.swift.codegen.restxml.httpResponse
77

8+
import software.amazon.smithy.aws.swift.codegen.AWSClientRuntimeTypes.RestXML.ErrorResponseContainer
89
import software.amazon.smithy.aws.traits.protocols.RestXmlTrait
910
import software.amazon.smithy.model.knowledge.HttpBinding
1011
import software.amazon.smithy.model.shapes.BooleanShape
@@ -82,7 +83,8 @@ class AWSXMLHttpResponseTraitWithoutPayload(
8283
}
8384

8485
fun renderWithErrorResponseContainer(outputShapeName: String, bodyMembersWithoutQueryTrait: Set<String>) {
85-
writer.write("let output: ErrorResponseContainer<${outputShapeName}Body> = try responseDecoder.decode(responseBody: data)")
86+
writer.addImport(ErrorResponseContainer)
87+
writer.write("let output: \$N<${outputShapeName}Body> = try responseDecoder.decode(responseBody: data)", ErrorResponseContainer)
8688
bodyMembersWithoutQueryTrait.sorted().forEach {
8789
writer.write("self.$it = output.error.$it")
8890
}

codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/ec2query/Ec2QueryHttpResponseBindingErrorGeneratorTests.kt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class Ec2QueryHttpResponseBindingErrorGeneratorTests {
6464
contents.shouldSyntacticSanityCheck()
6565
val expectedContents =
6666
"""
67-
extension ComplexError: AWSClientRuntime.AWSHttpServiceError {
67+
extension ComplexError {
6868
public init (httpResponse: ClientRuntime.HttpResponse, decoder: ClientRuntime.ResponseDecoder? = nil, message: Swift.String? = nil, requestID: Swift.String? = nil) throws {
6969
if case .stream(let reader) = httpResponse.body,
7070
let responseDecoder = decoder {
@@ -86,6 +86,36 @@ class Ec2QueryHttpResponseBindingErrorGeneratorTests {
8686
contents.shouldContainOnlyOnce(expectedContents)
8787
}
8888

89+
@Test
90+
fun `004 ComplexError constructor conforms to AWSHttpServiceError`() {
91+
val context = setupTests("ec2query/query-error.smithy", "aws.protocoltests.ec2#AwsEc2")
92+
val contents = TestContextGenerator.getFileContents(context.manifest, "/Example/models/ComplexError.swift")
93+
contents.shouldSyntacticSanityCheck()
94+
val expectedContents =
95+
"""
96+
public struct ComplexError: AWSClientRuntime.AWSHttpServiceError, Swift.Equatable {
97+
public var _headers: ClientRuntime.Headers?
98+
public var _statusCode: ClientRuntime.HttpStatusCode?
99+
public var _message: Swift.String?
100+
public var _requestID: Swift.String?
101+
public var _retryable: Swift.Bool = false
102+
public var _isThrottling: Swift.Bool = false
103+
public var _type: ClientRuntime.ErrorType = .client
104+
public var nested: AwsEc2ClientTypes.ComplexNestedErrorData?
105+
public var topLevel: Swift.String?
106+
107+
public init (
108+
nested: AwsEc2ClientTypes.ComplexNestedErrorData? = nil,
109+
topLevel: Swift.String? = nil
110+
)
111+
{
112+
self.nested = nested
113+
self.topLevel = topLevel
114+
}
115+
}
116+
""".trimIndent()
117+
contents.shouldContainOnlyOnce(expectedContents)
118+
}
89119
private fun setupTests(smithyFile: String, serviceShapeId: String): TestContext {
90120
val context =
91121
TestContextGenerator.initContextFrom(smithyFile, serviceShapeId, Ec2QueryTrait.ID, "ec2query", "ec2query")

codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/restxml/AWSRestXMLHttpResponseBindingErrorGeneratorTests.kt

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class AWSRestXMLHttpResponseBindingErrorGeneratorTests {
6464
contents.shouldSyntacticSanityCheck()
6565
val expectedContents =
6666
"""
67-
extension ComplexXMLError: AWSClientRuntime.AWSHttpServiceError {
67+
extension ComplexXMLError {
6868
public init (httpResponse: ClientRuntime.HttpResponse, decoder: ClientRuntime.ResponseDecoder? = nil, message: Swift.String? = nil, requestID: Swift.String? = nil) throws {
6969
if let headerHeaderValue = httpResponse.headers.value(for: "X-Header") {
7070
self.header = headerHeaderValue
@@ -74,7 +74,7 @@ class AWSRestXMLHttpResponseBindingErrorGeneratorTests {
7474
if case .stream(let reader) = httpResponse.body,
7575
let responseDecoder = decoder {
7676
let data = reader.toBytes().toData()
77-
let output: ErrorResponseContainer<ComplexXMLErrorBody> = try responseDecoder.decode(responseBody: data)
77+
let output: AWSClientRuntime.ErrorResponseContainer<ComplexXMLErrorBody> = try responseDecoder.decode(responseBody: data)
7878
self.nested = output.error.nested
7979
self.topLevel = output.error.topLevel
8080
} else {
@@ -90,15 +90,47 @@ class AWSRestXMLHttpResponseBindingErrorGeneratorTests {
9090
""".trimIndent()
9191
contents.shouldContainOnlyOnce(expectedContents)
9292
}
93-
9493
@Test
95-
fun `004 ComplexXMLErrorNoErrorWrapping Init renders without container`() {
94+
fun `004 ComplexXMLError extends from AWSHttpServiceError`() {
95+
val context = setupTests("restxml/xml-errors.smithy", "aws.protocoltests.restxml#RestXml")
96+
val contents = getFileContents(context.manifest, "/Example/models/ComplexXMLError.swift")
97+
contents.shouldSyntacticSanityCheck()
98+
val expectedContents =
99+
"""
100+
public struct ComplexXMLError: AWSClientRuntime.AWSHttpServiceError, Swift.Equatable {
101+
public var _headers: ClientRuntime.Headers?
102+
public var _statusCode: ClientRuntime.HttpStatusCode?
103+
public var _message: Swift.String?
104+
public var _requestID: Swift.String?
105+
public var _retryable: Swift.Bool = false
106+
public var _isThrottling: Swift.Bool = false
107+
public var _type: ClientRuntime.ErrorType = .client
108+
public var header: Swift.String?
109+
public var nested: RestXmlClientTypes.ComplexXMLNestedErrorData?
110+
public var topLevel: Swift.String?
111+
112+
public init (
113+
header: Swift.String? = nil,
114+
nested: RestXmlClientTypes.ComplexXMLNestedErrorData? = nil,
115+
topLevel: Swift.String? = nil
116+
)
117+
{
118+
self.header = header
119+
self.nested = nested
120+
self.topLevel = topLevel
121+
}
122+
}
123+
""".trimIndent()
124+
contents.shouldContainOnlyOnce(expectedContents)
125+
}
126+
@Test
127+
fun `005 ComplexXMLErrorNoErrorWrapping Init renders without container`() {
96128
val context = setupTests("restxml/xml-errors-noerrorwrapping.smithy", "aws.protocoltests.restxml#RestXml")
97129
val contents = getFileContents(context.manifest, "/Example/models/ComplexXMLErrorNoErrorWrapping+Init.swift")
98130
contents.shouldSyntacticSanityCheck()
99131
val expectedContents =
100132
"""
101-
extension ComplexXMLErrorNoErrorWrapping: AWSClientRuntime.AWSHttpServiceError {
133+
extension ComplexXMLErrorNoErrorWrapping {
102134
public init (httpResponse: ClientRuntime.HttpResponse, decoder: ClientRuntime.ResponseDecoder? = nil, message: Swift.String? = nil, requestID: Swift.String? = nil) throws {
103135
if let headerHeaderValue = httpResponse.headers.value(for: "X-Header") {
104136
self.header = headerHeaderValue

0 commit comments

Comments
 (0)