AbstractErrorParser.php
11 months ago
JsonParserTrait.php
11 months ago
JsonRpcErrorParser.php
11 months ago
RestJsonErrorParser.php
11 months ago
XmlErrorParser.php
11 months ago
XmlErrorParser.php
112 lines
| 1 | <?php |
| 2 | namespace Aws\Api\ErrorParser; |
| 3 | |
| 4 | use Aws\Api\Parser\PayloadParserTrait; |
| 5 | use Aws\Api\Parser\XmlParser; |
| 6 | use Aws\Api\Service; |
| 7 | use Aws\Api\StructureShape; |
| 8 | use Aws\CommandInterface; |
| 9 | use Psr\Http\Message\ResponseInterface; |
| 10 | |
| 11 | /** |
| 12 | * Parses XML errors. |
| 13 | */ |
| 14 | class XmlErrorParser extends AbstractErrorParser |
| 15 | { |
| 16 | use PayloadParserTrait; |
| 17 | |
| 18 | protected $parser; |
| 19 | |
| 20 | public function __construct(Service $api = null, XmlParser $parser = null) |
| 21 | { |
| 22 | parent::__construct($api); |
| 23 | $this->parser = $parser ?: new XmlParser(); |
| 24 | } |
| 25 | |
| 26 | public function __invoke( |
| 27 | ResponseInterface $response, |
| 28 | CommandInterface $command = null |
| 29 | ) { |
| 30 | $code = (string) $response->getStatusCode(); |
| 31 | |
| 32 | $data = [ |
| 33 | 'type' => $code[0] == '4' ? 'client' : 'server', |
| 34 | 'request_id' => null, |
| 35 | 'code' => null, |
| 36 | 'message' => null, |
| 37 | 'parsed' => null |
| 38 | ]; |
| 39 | |
| 40 | $body = $response->getBody(); |
| 41 | if ($body->getSize() > 0) { |
| 42 | $this->parseBody($this->parseXml($body, $response), $data); |
| 43 | } else { |
| 44 | $this->parseHeaders($response, $data); |
| 45 | } |
| 46 | |
| 47 | $this->populateShape($data, $response, $command); |
| 48 | |
| 49 | return $data; |
| 50 | } |
| 51 | |
| 52 | private function parseHeaders(ResponseInterface $response, array &$data) |
| 53 | { |
| 54 | if ($response->getStatusCode() == '404') { |
| 55 | $data['code'] = 'NotFound'; |
| 56 | } |
| 57 | |
| 58 | $data['message'] = $response->getStatusCode() . ' ' |
| 59 | . $response->getReasonPhrase(); |
| 60 | |
| 61 | if ($requestId = $response->getHeaderLine('x-amz-request-id')) { |
| 62 | $data['request_id'] = $requestId; |
| 63 | $data['message'] .= " (Request-ID: $requestId)"; |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | private function parseBody(\SimpleXMLElement $body, array &$data) |
| 68 | { |
| 69 | $data['parsed'] = $body; |
| 70 | $prefix = $this->registerNamespacePrefix($body); |
| 71 | |
| 72 | if ($tempXml = $body->xpath("//{$prefix}Code[1]")) { |
| 73 | $data['code'] = (string) $tempXml[0]; |
| 74 | } |
| 75 | |
| 76 | if ($tempXml = $body->xpath("//{$prefix}Message[1]")) { |
| 77 | $data['message'] = (string) $tempXml[0]; |
| 78 | } |
| 79 | |
| 80 | $tempXml = $body->xpath("//{$prefix}RequestId[1]"); |
| 81 | if (isset($tempXml[0])) { |
| 82 | $data['request_id'] = (string)$tempXml[0]; |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | protected function registerNamespacePrefix(\SimpleXMLElement $element) |
| 87 | { |
| 88 | $namespaces = $element->getDocNamespaces(); |
| 89 | if (!isset($namespaces[''])) { |
| 90 | return ''; |
| 91 | } |
| 92 | |
| 93 | // Account for the default namespace being defined and PHP not |
| 94 | // being able to handle it :(. |
| 95 | $element->registerXPathNamespace('ns', $namespaces['']); |
| 96 | return 'ns:'; |
| 97 | } |
| 98 | |
| 99 | protected function payload( |
| 100 | ResponseInterface $response, |
| 101 | StructureShape $member |
| 102 | ) { |
| 103 | $xmlBody = $this->parseXml($response->getBody(), $response); |
| 104 | $prefix = $this->registerNamespacePrefix($xmlBody); |
| 105 | $errorBody = $xmlBody->xpath("//{$prefix}Error"); |
| 106 | |
| 107 | if (is_array($errorBody) && !empty($errorBody[0])) { |
| 108 | return $this->parser->parse($member, $errorBody[0]); |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 |