diff --git a/smithy-aws-protocol-tests/model/aws-config.smithy b/smithy-aws-protocol-tests/model/aws-config.smithy index 321956d6246..1679c0944d0 100644 --- a/smithy-aws-protocol-tests/model/aws-config.smithy +++ b/smithy-aws-protocol-tests/model/aws-config.smithy @@ -109,3 +109,30 @@ enum RetryMode { STANDARD = "standard" ADAPTIVE = "adaptive" } + +/// Vendor params to use when making assertions about error code or query +/// error type. +structure ErrorCodeParams { + /// The error code exposed to the customer. + /// + /// If the SDK exposes the error code to customers, this value MUST be + /// asserted to match the exposed error code. + /// + /// This is modifiable by the awsQueryError trait. For services with + /// awsQueryCompatible, it will be exposed in the `x-amzn-query-error` + /// header which takes the form `Code;Fault`. This value represents + /// the `Code` portion. + @required + code: String + + /// The query error type exposed to the customer. + /// + /// If the SDK exposes the query error type to customers, this value MUST be + /// asserted to match the exposed query error type. + /// + /// This is modifiable by the awsQueryError trait. For services with + /// awsQueryCompatible, it will be exposed in the `x-amzn-query-error` + /// header which takes the form `Code;Fault`. This value represents + /// the `Fault` portion. + type: String +} diff --git a/smithy-aws-protocol-tests/model/awsJson1_0/main.smithy b/smithy-aws-protocol-tests/model/awsJson1_0/main.smithy index f7314548b3a..2bd7668102d 100644 --- a/smithy-aws-protocol-tests/model/awsJson1_0/main.smithy +++ b/smithy-aws-protocol-tests/model/awsJson1_0/main.smithy @@ -5,6 +5,7 @@ namespace aws.protocoltests.json10 use aws.api#service use aws.auth#sigv4 use aws.protocols#awsJson1_0 +use aws.protocols#awsQueryCompatible use smithy.test#httpRequestTests use smithy.test#httpResponseTests @@ -42,5 +43,20 @@ service JsonRpc10 { OperationWithRequiredMembers, OperationWithNestedStructure OperationWithRequiredMembersWithDefaults + + QueryIncompatibleOperation + ] +} + + +@service(sdkId: "Query Compatible JSON RPC 10") +@sigv4(name: "query-compatible-jsonrpc10") +@awsJson1_0 +@title("Query Compatible Json 1.0 Protocol Service") +@awsQueryCompatible +service QueryCompatibleJsonRpc10 { + version: "2020-07-14", + operations: [ + QueryCompatibleOperation ] } diff --git a/smithy-aws-protocol-tests/model/awsJson1_0/query-compatible.smithy b/smithy-aws-protocol-tests/model/awsJson1_0/query-compatible.smithy new file mode 100644 index 00000000000..dc30be6a2ce --- /dev/null +++ b/smithy-aws-protocol-tests/model/awsJson1_0/query-compatible.smithy @@ -0,0 +1,94 @@ +$version: "2.0" + +namespace aws.protocoltests.json10 + +use aws.protocols#awsJson1_0 +use aws.protocols#awsQueryError +use aws.protocoltests.config#ErrorCodeParams +use smithy.test#httpRequestTests +use smithy.test#httpResponseTests + +@httpRequestTests([ + { + id: "NonQueryCompatibleAwsJson10ForbidsQueryModeHeader" + documentation: "The query mode header MUST NOT be set on non-query-compatible services." + protocol: awsJson1_0 + method: "POST" + headers: { "Content-Type": "application/x-amz-json-1.0", "X-Amz-Target": "JsonRpc10.QueryIncompatibleOperation" } + uri: "/" + body: "{}" + bodyMediaType: "application/json" + } +]) +@idempotent +operation QueryIncompatibleOperation {} + +@idempotent +operation QueryCompatibleOperation { + errors: [ + NoCustomCodeError + CustomCodeError + ] +} + +apply QueryCompatibleOperation @httpRequestTests([ + { + id: "QueryCompatibleAwsJson10CborSendsQueryModeHeader" + documentation: "Clients for query-compatible services MUST send the x-amzn-query-mode header." + protocol: awsJson1_0 + method: "POST" + headers: { "Content-Type": "application/x-amz-json-1.0", "x-amzn-query-mode": "true", "X-Amz-Target": "QueryCompatibleJsonRpc10.QueryCompatibleOperation" } + uri: "/" + body: "{}" + bodyMediaType: "application/json" + } +]) + +@error("client") +structure NoCustomCodeError { + message: String +} + +apply NoCustomCodeError @httpResponseTests([ + { + id: "QueryCompatibleAwsJson10CborNoCustomCodeError" + documentation: "Parses simple errors with no query error code" + protocol: awsJson1_0 + params: { message: "Hi" } + code: 400 + headers: { "Content-Type": "application/x-amz-json-1.0" } + body: """ + { + "__type": "aws.protocoltests.json10#NoCustomCodeError", + "Message": "Hi" + }""" + bodyMediaType: "application/json" + vendorParamsShape: ErrorCodeParams + vendorParams: { code: "NoCustomCodeError" } + } +]) + +@awsQueryError(code: "Customized", httpResponseCode: 402) +@error("client") +structure CustomCodeError { + message: String +} + +apply CustomCodeError @httpResponseTests([ + { + id: "QueryCompatibleAwsJson10CustomCodeError" + documentation: "Parses simple errors with query error code" + protocol: awsJson1_0 + params: { message: "Hi" } + code: 400 + headers: { "Content-Type": "application/x-amz-json-1.0", "x-amzn-query-error": "Customized;Sender" } + body: """ + { + "__type": "aws.protocoltests.json10#CustomCodeError", + "Message": "Hi" + }""" + bodyMediaType: "application/json" + vendorParamsShape: ErrorCodeParams + vendorParams: { code: "Customized", type: "Sender" } + } +]) diff --git a/smithy-aws-protocol-tests/model/awsQuery/xml-errors.smithy b/smithy-aws-protocol-tests/model/awsQuery/xml-errors.smithy index 3d64b5626ee..c21141487ba 100644 --- a/smithy-aws-protocol-tests/model/awsQuery/xml-errors.smithy +++ b/smithy-aws-protocol-tests/model/awsQuery/xml-errors.smithy @@ -29,6 +29,7 @@ namespace aws.protocoltests.query use aws.protocols#awsQueryError use aws.protocols#awsQuery +use aws.protocoltests.config#ErrorCodeParams use smithy.test#httpResponseTests /// This operation has three possible return values: @@ -97,6 +98,11 @@ apply InvalidGreeting @httpResponseTests([ """, bodyMediaType: "application/xml", + vendorParamsShape: ErrorCodeParams + vendorParams: { + code: "InvalidGreeting" + type: "Sender" + } } ]) @@ -136,6 +142,11 @@ apply ComplexError @httpResponseTests([ """, bodyMediaType: "application/xml", + vendorParamsShape: ErrorCodeParams + vendorParams: { + code: "ComplexError" + type: "Sender" + } } ]) @@ -175,5 +186,10 @@ apply CustomCodeError @httpResponseTests([ """, bodyMediaType: "application/xml", + vendorParamsShape: ErrorCodeParams + vendorParams: { + code: "Customized" + type: "Sender" + } } ]) diff --git a/smithy-aws-protocol-tests/model/ec2Query/xml-errors.smithy b/smithy-aws-protocol-tests/model/ec2Query/xml-errors.smithy index fec1cd73bd1..0dc82379080 100644 --- a/smithy-aws-protocol-tests/model/ec2Query/xml-errors.smithy +++ b/smithy-aws-protocol-tests/model/ec2Query/xml-errors.smithy @@ -23,6 +23,7 @@ $version: "2.0" namespace aws.protocoltests.ec2 use aws.protocols#ec2Query +use aws.protocoltests.config#ErrorCodeParams use smithy.test#httpResponseTests /// This operation has three possible return values: @@ -91,6 +92,10 @@ apply InvalidGreeting @httpResponseTests([ params: { Message: "Hi" }, + vendorParamsShape: ErrorCodeParams + vendorParams: { + code: "InvalidGreeting" + } } ]) @@ -132,6 +137,10 @@ apply ComplexError @httpResponseTests([ """, bodyMediaType: "application/xml", + vendorParamsShape: ErrorCodeParams + vendorParams: { + code: "ComplexError" + } } ]) diff --git a/smithy-aws-protocol-tests/model/rpcv2Cbor/main.smithy b/smithy-aws-protocol-tests/model/rpcv2Cbor/main.smithy new file mode 100644 index 00000000000..371a3260054 --- /dev/null +++ b/smithy-aws-protocol-tests/model/rpcv2Cbor/main.smithy @@ -0,0 +1,31 @@ +$version: "2" + +namespace aws.protocoltests.rpcv2cbor + +use aws.api#service +use aws.auth#sigv4 +use aws.protocols#awsQueryCompatible +use smithy.protocols#rpcv2Cbor + +@service(sdkId: "Query Compatible RpcV2 Protocol") +@sigv4(name: "query-compatible-rpcv2") +@rpcv2Cbor +@title("Query Compatible RpcV2 Protocol Service") +@awsQueryCompatible +service QueryCompatibleRpcV2Protocol { + version: "2025-06-20" + operations: [ + QueryCompatibleOperation + ] +} + +@service(sdkId: "Non Query Compatible RpcV2 Protocol") +@sigv4(name: "non-query-compatible-rpcv2") +@rpcv2Cbor +@title("Non Query Compatible RpcV2 Protocol Service") +service NonQueryCompatibleRpcV2Protocol { + version: "2025-06-20" + operations: [ + QueryIncompatibleOperation + ] +} diff --git a/smithy-aws-protocol-tests/model/rpcv2Cbor/query-compatible.smithy b/smithy-aws-protocol-tests/model/rpcv2Cbor/query-compatible.smithy new file mode 100644 index 00000000000..aa6e6ab5552 --- /dev/null +++ b/smithy-aws-protocol-tests/model/rpcv2Cbor/query-compatible.smithy @@ -0,0 +1,87 @@ +$version: "2" + +namespace aws.protocoltests.rpcv2cbor + +use aws.protocols#awsQueryError +use aws.protocoltests.config#ErrorCodeParams +use smithy.protocols#rpcv2Cbor +use smithy.test#httpRequestTests +use smithy.test#httpResponseTests + +@httpRequestTests([ + { + id: "NonQueryCompatibleRpcV2CborForbidsQueryModeHeader" + documentation: "The query mode header MUST NOT be set on non-query-compatible services." + protocol: rpcv2Cbor + method: "POST" + headers: { "smithy-protocol": "rpc-v2-cbor", Accept: "application/cbor" } + forbidHeaders: ["x-amzn-query-mode"] + uri: "/service/NonQueryCompatibleRpcV2Protocol/operation/QueryIncompatibleOperation" + body: "{}" + bodyMediaType: "application/json" + } +]) +@idempotent +operation QueryIncompatibleOperation {} + +@idempotent +operation QueryCompatibleOperation { + errors: [ + NoCustomCodeError + CustomCodeError + ] +} + +apply QueryCompatibleOperation @httpRequestTests([ + { + id: "QueryCompatibleRpcV2CborSendsQueryModeHeader" + documentation: "Clients for query-compatible services MUST send the x-amzn-query-mode header." + protocol: rpcv2Cbor + method: "POST" + headers: { "smithy-protocol": "rpc-v2-cbor", Accept: "application/cbor", "x-amzn-query-mode": "true" } + forbidHeaders: ["Content-Type", "X-Amz-Target"] + uri: "/service/QueryCompatibleRpcV2Protocol/operation/QueryCompatibleOperation" + body: "" + } +]) + +@error("client") +structure NoCustomCodeError { + message: String +} + +apply NoCustomCodeError @httpResponseTests([ + { + id: "QueryCompatibleRpcV2CborNoCustomCodeError" + documentation: "Parses simple RpcV2 CBOR errors with no query error code" + protocol: rpcv2Cbor + params: { message: "Hi" } + code: 400 + headers: { "smithy-protocol": "rpc-v2-cbor", "Content-Type": "application/cbor" } + body: "v2ZfX3R5cGV4MHNtaXRoeS5wcm90b2NvbHRlc3RzLnJwY3YyQ2JvciNOb0N1c3RvbUNvZGVFcnJvcmdNZXNzYWdlYkhp/w==" + bodyMediaType: "application/cbor" + vendorParamsShape: ErrorCodeParams + vendorParams: { code: "NoCustomCodeError" } + } +]) + +@awsQueryError(code: "Customized", httpResponseCode: 402) +@error("client") +structure CustomCodeError { + message: String +} + +apply CustomCodeError @httpResponseTests([ + { + id: "QueryCompatibleRpcV2CborCustomCodeError" + documentation: "Parses simple RpcV2 CBOR errors with query error code" + protocol: rpcv2Cbor + params: { message: "Hi" } + code: 400 + headers: { "smithy-protocol": "rpc-v2-cbor", "Content-Type": "application/cbor", "x-amzn-query-error": "Customized;Sender" } + body: "v2ZfX3R5cGV4LnNtaXRoeS5wcm90b2NvbHRlc3RzLnJwY3YyQ2JvciNDdXN0b21Db2RlRXJyb3JnTWVzc2FnZWJIaf8=" + bodyMediaType: "application/cbor" + vendorParamsShape: ErrorCodeParams + vendorParams: { code: "Customized", type: "Sender" } + } +])