Unverified Commit 41286629 authored by codypenta's avatar codypenta Committed by GitHub
Browse files

Fix error struct with default impl (#3190)



## 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: default avatarJohn DiSanti <john@vinylsquid.com>
parent 0b604d7f
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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"]
+3 −1
Original line number Diff line number Diff line
@@ -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
@@ -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() {
+71 −0
Original line number Diff line number Diff line
/*
 * 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) { _, _ -> }
    }
}