Skip to content

Commit

Permalink
Throw a ParserException when content is unparseable
Browse files Browse the repository at this point in the history
  • Loading branch information
jeskew committed Sep 10, 2015
1 parent 42e16d6 commit 0494e06
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/Api/Parser/Exception/ParserException.php
@@ -0,0 +1,4 @@
<?php
namespace Aws\Api\Parser\Exception;

class ParserException extends \RuntimeException {}
4 changes: 3 additions & 1 deletion src/Api/Parser/JsonRpcParser.php
Expand Up @@ -11,6 +11,8 @@
*/
class JsonRpcParser extends AbstractParser
{
use PayloadParserTrait;

private $parser;

/**
Expand All @@ -31,7 +33,7 @@ public function __invoke(

return new Result($this->parser->parse(
$operation->getOutput(),
json_decode($response->getBody(), true)
$this->parseJson($response->getBody())
));
}
}
51 changes: 51 additions & 0 deletions src/Api/Parser/PayloadParserTrait.php
@@ -0,0 +1,51 @@
<?php
namespace Aws\Api\Parser;

use Aws\Api\Parser\Exception\ParserException;

trait PayloadParserTrait
{
/**
* @param string $json
*
* @throws ParserException
*
* @return array
*/
private function parseJson($json)
{
$jsonPayload = json_decode($json, true);

if (JSON_ERROR_NONE !== json_last_error()) {
throw new ParserException('Error parsing JSON: '
. json_last_error_msg());
}

return $jsonPayload;
}

/**
* @param string $xml
*
* @throws ParserException
*
* @return \SimpleXMLElement
*/
private function parseXml($xml)
{
$priorSetting = libxml_use_internal_errors(true);
try {
libxml_clear_errors();
$xmlPayload = new \SimpleXMLElement($xml);
if ($error = libxml_get_last_error()) {
throw new \RuntimeException($error->message);
}
} catch (\Exception $e) {
throw new ParserException("Error parsing XML: {$e->getMessage()}", 0, $e);
} finally {
libxml_use_internal_errors($priorSetting);
}

return $xmlPayload;
}
}
4 changes: 3 additions & 1 deletion src/Api/Parser/QueryParser.php
Expand Up @@ -11,6 +11,8 @@
*/
class QueryParser extends AbstractParser
{
use PayloadParserTrait;

/** @var XmlParser */
private $xmlParser;

Expand Down Expand Up @@ -39,7 +41,7 @@ public function __invoke(
ResponseInterface $response
) {
$output = $this->api->getOperation($command->getName())->getOutput();
$xml = new \SimpleXMLElement($response->getBody());
$xml = $this->parseXml($response->getBody());

if ($this->honorResultWrapper && $output['resultWrapper']) {
$xml = $xml->{$output['resultWrapper']};
Expand Down
4 changes: 3 additions & 1 deletion src/Api/Parser/RestJsonParser.php
Expand Up @@ -10,6 +10,8 @@
*/
class RestJsonParser extends AbstractRestParser
{
use PayloadParserTrait;

/** @var JsonParser */
private $parser;

Expand All @@ -28,7 +30,7 @@ protected function payload(
StructureShape $member,
array &$result
) {
$jsonBody = json_decode($response->getBody(), true);
$jsonBody = $this->parseJson($response->getBody());

if ($jsonBody) {
$result += $this->parser->parse($member, $jsonBody);
Expand Down
4 changes: 3 additions & 1 deletion src/Api/Parser/RestXmlParser.php
Expand Up @@ -10,6 +10,8 @@
*/
class RestXmlParser extends AbstractRestParser
{
use PayloadParserTrait;

/** @var XmlParser */
private $parser;

Expand All @@ -28,7 +30,7 @@ protected function payload(
StructureShape $member,
array &$result
) {
$xml = new \SimpleXMLElement($response->getBody());
$xml = $this->parseXml($response->getBody());
$result += $this->parser->parse($member, $xml);
}
}
6 changes: 3 additions & 3 deletions src/S3/MalformedResponseParser.php
Expand Up @@ -2,9 +2,9 @@
namespace Aws\S3;

use Aws\Api\Parser\AbstractParser;
use Aws\Api\Parser\Exception\ParserException;
use Aws\CommandInterface;
use Aws\Exception\AwsException;
use Exception;
use Psr\Http\Message\ResponseInterface;

class MalformedResponseParser extends AbstractParser
Expand All @@ -30,10 +30,10 @@ public function __invoke(

try {
return $fn($command, $response);
} catch (Exception $e) {
} catch (ParserException $e) {
throw new $this->exceptionClass(
"Error parsing response for {$command->getName()}:"
. " AWS parsing error: {$e->getMessage()}",
. " AWS parsing error: {$e->getMessage()}",
$command,
['connection_error' => true, 'exception' => $e],
$e
Expand Down
4 changes: 2 additions & 2 deletions tests/DynamoDb/DynamoDbClientTest.php
Expand Up @@ -79,8 +79,8 @@ public function dataForFormatValueTest()
public function testValidatesAndRetriesCrc32()
{
$queue = [
new Response(200, ['x-amz-crc32' => '123'], 'foo'),
new Response(200, ['x-amz-crc32' => '2356372769'], 'foo')
new Response(200, ['x-amz-crc32' => '123'], '"foo"'),
new Response(200, ['x-amz-crc32' => '400595255'], '"foo"')
];

$handler = function ($request, $options) use (&$queue) {
Expand Down

0 comments on commit 0494e06

Please sign in to comment.