Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix response payload and incorrectly parsing error response #63

Merged
merged 4 commits into from
Dec 27, 2019

Conversation

AllanZhengYP
Copy link
Contributor

@AllanZhengYP AllanZhengYP commented Dec 24, 2019

TwoThree fixes:

  1. Currently when response body is a payload member, the SDK either
    keeps reponse intact if it has a streaming trait, or parse the body
    to JS object.

    Actually when response payload is not streaming, it is
    NOT always parsable(not a valid JSON or XML string). Specificly,
    when payload is scalar(Number, String, BigInteger, etc.), we shouldn't
    parse it with XML or JSON parser; We should also treat Blob shape
    differently as we should encode the binaries into string; Only when
    shape is Set, Map or Structure can we assume payload is parsable
    by JSON or XML parser.

  2. For some protocols, error type flag exists in error response body,
    then we need to collect response stream to JS object and parse the
    error type; For other protocols, error type flag doesn't exist in
    error response body, then we don't need to collect the response
    stream in error dispatcher. Instead, we can treat the error like
    normal response. So that error shape supports the same traits as
    normal responses like streaming, payload etc.

    This is done by adding a new flag in Protocol generator--
    isErrorCodeInBody. When it return true, it means error type flag
    exists in error response body, then body is parsed in errors
    dispatcher, and each error deser only need to deal with parsed
    response body in JS object format. When it returns false, it means
    error type can be inferred without touching response body, then
    error deser can access the error response intact.

  3. UPDATED: If incoming error response is unknow error, we only
    make best effort to infer the error type. This change puts error response
    body string to error message so that users can have more information.
    This change is necessary for Node because when error response is
    unknown, the body stream will never be consumed, which would stay in
    memory for a long time before it resolves automaticly.

This PR is based on presumptions:

  1. When response is bond to DOCUMENT, the body CANNOT be
    streaming, and can be parsed to JS object.

/cc @kstich

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

For some protocols, error type flag exists in error response body,
then we need to collect response stream to JS object and parse the
error type; For other protocols, error type flag doesn't exist in
error response body, then we don't need to collect the response
stream in error dispatcher. Instead, we can treat the error like
normal response. So that error shape supports the same traits as
normal responses like streaming, payload etc.

This is done by add a new flag in Protocol generator--
isErrorCodeInBody. When it return true, it means error type flag
exists in error response body, then body is parsed in errors
dispatcher, and each error deser only need to deal with parsed
response body in JS object format. When it returns false, it means
error type can be inferred without touching response body, then
error deser can access the error response intact.
@JordonPhillips
Copy link
Contributor

Only when shape is Set, Map or Structure can we assume payload is parsable by JSON or XML parser.

The http payload trait can only be bound to strings, blobs, structures, and unions

} else if (target instanceof BlobShape) {
// If payload is blob, only need to collect stream to binary data(Uint8Array).
writer.write("const data: any = await collectBody(output.body, context);");
} else if (target instanceof CollectionShape || target instanceof StructureShape) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will never be a collection, but it could be a union

@@ -108,6 +108,30 @@ static void generateMetadataDeserializer(GenerationContext context, SymbolRefere
writer.write("");
}

static void generateCollectBody(GenerationContext context) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add doc strings to these?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear I meant method-level javadocs as all the other methods in this class have.

// then we collect body and parse it to JS object, otherwise leave the response body as is.
writer.openBlock(
"const $L: any = {", "};", shouldParseErrorBody ? "parsedOutput" : "errorOutput", () -> {
writer.write("...output,");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation is off here

Copy link
Contributor

@JordonPhillips JordonPhillips left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs previously asked for are still needed, but everything else looks fine

If incoming error response is unknow error, we only make best effort
to infer the error type. This change puts error response body to error
message so that users have the information they need. This change is
necessary for Node because when error response is unknown, the body
stream will never be consumed, which would use a lot of resources
before stream is flushed.
@AllanZhengYP
Copy link
Contributor Author

Can this get merged? (I don't have permission)

@srchase srchase merged commit 44a72fe into smithy-lang:master Dec 27, 2019
kstich added a commit that referenced this pull request Dec 27, 2019
kstich added a commit that referenced this pull request Dec 27, 2019
srchase pushed a commit to srchase/smithy-typescript that referenced this pull request Mar 17, 2023
…ang#63)

* fix when response payload is not structured string

* add support for parsing body in either dispatcher or deser

For some protocols, error type flag exists in error response body,
then we need to collect response stream to JS object and parse the
error type; For other protocols, error type flag doesn't exist in
error response body, then we don't need to collect the response
stream in error dispatcher. Instead, we can treat the error like
normal response. So that error shape supports the same traits as
normal responses like streaming, payload etc.

This is done by add a new flag in Protocol generator--
isErrorCodeInBody. When it return true, it means error type flag
exists in error response body, then body is parsed in errors
dispatcher, and each error deser only need to deal with parsed
response body in JS object format. When it returns false, it means
error type can be inferred without touching response body, then
error deser can access the error response intact.

* address feedbacks: fix indentation; readResponseBody; add docs

* add response body string to unknown error message

If incoming error response is unknow error, we only make best effort
to infer the error type. This change puts error response body to error
message so that users have the information they need. This change is
necessary for Node because when error response is unknown, the body
stream will never be consumed, which would use a lot of resources
before stream is flushed.
srchase pushed a commit to srchase/smithy-typescript that referenced this pull request Mar 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants