fix: add streaming flag and error handling#3214
fix: add streaming flag and error handling#3214yenfryherrerafeliz wants to merge 18 commits intoaws:masterfrom
Conversation
- Evaluates if a client's operation requires http streaming flag to be set to true, and if so then it pass the option along. - Make error parsers to reused a parsed body for scenario where the body is non seekable and can't be consumed again. Also change the condition: (!$body->isSeekable() || $body->getSize()) To: (!$body->isSeekable() || !$body->getSize()) The reason is that a stream non seekable will most likely not have a size, which means this condition will always be true.
Reverted the condition to what it was: (!$body->isSeekable() || $body->getSize()) Why?, I need to understand better what is the usage of this condition before changing. It was breaking some integ tests.
- When a response body is empty then we dont try to parse it. - When the response body is non seekable then, we read the full body before parsing.
|
- Remove lowercasing parsed in rest json error parser.
Error is parsed when the body of the response is not seekable.
| throw new \RuntimeException('The HTTP handler was rejected without an "exception" key value pair.'); | ||
| } | ||
|
|
||
| $serviceError = "AWS HTTP error: " . $err['exception']->getMessage(); |
There was a problem hiding this comment.
The change in format might affect log parsing. I'd leave this unless it's accounted for later
There was a problem hiding this comment.
I basically changed this because it was duplicating the error message. What I did in specific was to append the message from the exception when a response is not available, but, if we have a response then we just use the error message from the deserialization process.
if (!isset($err['response'])) {
$parts = ['response' => null];
$serviceError .= $err['exception']->getMessage(); // MOVED HERE.
}When the response body is a non seekable stream, which happens when the stream flag is set in the request, the parser condition to do a parsing is evaluated to true, but in empty payloads, such as when doing head requests, it fails. To remedy this we read the full body content and evaluate whether the returned value is empty before parsing.
To make a body content to be fully available always in implementations a response wrapper class has been created that takes in a response and evaluates if the body is non-seekable then it wrappes it into a CachingStream that will allow the body to rewind.
Overwrites responses on non-seekable streams by wrapping the non-seekable body on a CachingStream to allow rewind.
Avoid consuming original body before it is cached.
|
stobrien89
left a comment
There was a problem hiding this comment.
A few more comments and an old one (log parsing) that needs to be addressed
| if ($body->isSeekable()) { | ||
| $body->rewind(); | ||
| } | ||
|
|
||
| $rawBody = $body->getContents(); | ||
| if (!empty($rawBody)) { | ||
| $parsedBody = $this->parseJson($rawBody, $response); | ||
| } |
There was a problem hiding this comment.
Could this logic and the logic in payload() for JSON and XML parsers be moved into the abstract parsers?
There was a problem hiding this comment.
This logic is like a generic method for parsing JSON payload and is used by JsonRpcErrorParser and RestJsonErrorParser, and actually it was already there; I just changed a few things such as the empty content evaluation, etc.
Regarding moving payload into the abstract class, I think we could, but I would like to understand more why we want to do it?
Issues #3124, #3018, #3181:
Description of changes:
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.