Skip to content

Commit

Permalink
Fix error struct with default impl (#3190)
Browse files Browse the repository at this point in the history
## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here -->

When an error member has a default value, it will generate errors
(specifically is_none not found on type String) with smithy-rs client
unless you manually specify @required

More Here: #3182

## Description
<!--- Describe your changes in detail -->

Adds recomendation change to address error structures with a default
implementation like so:

```kotlin
if (errorMessageMember != null) {
    val symbol = symbolProvider.toSymbol(errorMessageMember)
    if (symbol.isOptional()) {
        rust(
            """
            if tmp.message.is_none() {
                tmp.message = _error_message;
            }
            """,
        )
    }
}
..... 
```


```smithy
@error("client")
structure Error {
    @required
    requestId: String

    @required
    message: String

    code: String = "400"

    context: String
}
```

## Testing
<!--- Please describe in detail how you tested your changes -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->

Added the above and ran `./gradlew codegen-client-test:build` with a
build successful

## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it
rather than leaving it unchecked -->
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the
smithy-rs codegen or runtime crates
- [ ] I have updated `CHANGELOG.next.toml` if I made changes to the AWS
SDK, generated SDK code, or SDK runtime crates

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._

---------

Co-authored-by: John DiSanti <[email protected]>
  • Loading branch information
codypenta and jdisanti authored Nov 14, 2023
1 parent 0b604d7 commit 4128662
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 1 deletion.
8 changes: 8 additions & 0 deletions CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
# meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client | server | all"}
# author = "rcoh"

[[smithy-rs]]
message = """
Fix rendering of @error structs when fields have default values
"""
references = ["smithy-rs#3182"]
meta = { "breaking" = false, "tada" = false, "bug" = true, "target" = "client"}
author = "codypenta"

[[aws-sdk-rust]]
message = "Change `ByteStream::into_async_read` to return `AsyncBufRead`"
references = ["smithy-rs#3164"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider
import software.amazon.smithy.rust.codegen.core.smithy.customize.writeCustomizations
import software.amazon.smithy.rust.codegen.core.smithy.generators.setterName
import software.amazon.smithy.rust.codegen.core.smithy.isOptional
import software.amazon.smithy.rust.codegen.core.smithy.protocols.HttpBindingDescriptor
import software.amazon.smithy.rust.codegen.core.smithy.protocols.HttpLocation
import software.amazon.smithy.rust.codegen.core.smithy.protocols.Protocol
Expand Down Expand Up @@ -163,7 +164,8 @@ class ProtocolParserGenerator(
val errorMessageMember = errorShape.errorMessageMember()
// If the message member is optional and wasn't set, we set a generic error message.
if (errorMessageMember != null) {
if (errorMessageMember.isOptional) {
val symbol = symbolProvider.toSymbol(errorMessageMember)
if (symbol.isOptional()) {
rust(
"""
if tmp.message.is_none() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.rust.codegen.client.smithy.generators.protocol

import org.junit.jupiter.api.Test
import software.amazon.smithy.rust.codegen.client.testutil.clientIntegrationTest
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel

class ProtocolParserGeneratorTest {
private val model = """
${'$'}version: "2.0"
namespace test
use aws.protocols#restJson1
@restJson1
service TestService {
version: "2019-12-16",
operations: [SomeOperation]
errors: [SomeTopLevelError]
}
@http(uri: "/SomeOperation", method: "POST")
operation SomeOperation {
input: SomeOperationInputOutput,
output: SomeOperationInputOutput,
errors: [SomeOperationError]
}
structure SomeOperationInputOutput {
payload: String,
a: String,
b: Integer
}
@error("server")
structure SomeTopLevelError {
@required
requestId: String
@required
message: String
code: String = "400"
context: String
}
@error("client")
structure SomeOperationError {
@required
requestId: String
@required
message: String
code: String = "400"
context: String
}
"""
.asSmithyModel()

@Test
fun `generate an complex error structure that compiles`() {
clientIntegrationTest(model) { _, _ -> }
}
}

0 comments on commit 4128662

Please sign in to comment.