private function tryDeserializeError($response, $errorClass)
 {
     $error = $this->serializer->deserialize($response['body'], $response['transfer_stats']);
     if (is_array($error)) {
         // 2.0 structured exceptions
         if (isset($error['error']['reason'])) {
             // Try to use root cause first (only grabs the first root cause)
             $root = $error['error']['root_cause'];
             if (isset($root) && isset($root[0])) {
                 $cause = $root[0]['reason'];
                 $type = $root[0]['type'];
             } else {
                 $cause = $error['error']['reason'];
                 $type = $error['error']['type'];
             }
             $original = new $errorClass($response['body'], $response['status']);
             return new $errorClass("{$type}: {$cause}", $response['status'], $original);
         }
         if (isset($error['error'])) {
             // <2.0 semi-structured exceptions
             $original = new $errorClass($response['body'], $response['status']);
             return new $errorClass($error['error'], $response['status'], $original);
         }
         // <2.0 "i just blew up" nonstructured exception
         // $error is an array but we don't know the format, reuse the response body instead
         return new $errorClass($response['body'], $response['status']);
     }
     // <2.0 "i just blew up" nonstructured exception
     return new $errorClass($error, $response['status']);
 }
Пример #2
0
 /**
  * Perform a request to the Cluster
  *
  * @param string $method     HTTP method to use
  * @param string $uri        HTTP URI to send request to
  * @param null   $params     Optional query parameters
  * @param null   $body       Optional query body
  *
  * @throws Common\Exceptions\NoNodesAvailableException|\Exception
  * @internal param null $maxRetries Optional number of retries
  *
  * @return array
  */
 public function performRequest($method, $uri, $params = null, $body = null)
 {
     try {
         $connection = $this->getConnection();
     } catch (Exceptions\NoNodesAvailableException $exception) {
         $this->log->critical('No alive nodes found in cluster');
         throw $exception;
     }
     $response = array();
     $caughtException = null;
     $this->lastConnection = $connection;
     try {
         if (isset($body) === true) {
             $body = $this->serializer->serialize($body);
         }
         $response = $connection->performRequest($method, $uri, $params, $body);
         $connection->markAlive();
         $this->retryAttempts = 0;
         $data = $this->serializer->deserialize($response['text'], $response['info']);
         return array('status' => $response['status'], 'data' => $data, 'info' => $response['info']);
     } catch (Exceptions\Curl\OperationTimeoutException $exception) {
         $this->connectionPool->scheduleCheck();
         $caughtException = $exception;
     } catch (Exceptions\ClientErrorResponseException $exception) {
         throw $exception;
         //We need 4xx errors to go straight to the user, no retries
     } catch (Exceptions\ServerErrorResponseException $exception) {
         throw $exception;
         //We need 5xx errors to go straight to the user, no retries
     } catch (TransportException $exception) {
         $connection->markDead();
         $this->connectionPool->scheduleCheck();
         $caughtException = $exception;
     }
     $shouldRetry = $this->shouldRetry($method, $uri, $params, $body);
     if ($shouldRetry === true) {
         return $this->performRequest($method, $uri, $params, $body);
     }
     if ($caughtException !== null) {
         throw $caughtException;
     }
     return $response;
 }
 private function wrapHandler(callable $handler, LoggerInterface $logger, LoggerInterface $tracer)
 {
     return function (array $request, Connection $connection, Transport $transport = null, $options) use($handler, $logger, $tracer) {
         // Send the request using the wrapped handler.
         $response = Core::proxy($handler($request), function ($response) use($connection, $transport, $logger, $tracer, $request, $options) {
             if (isset($response['error']) === true) {
                 if ($response['error'] instanceof ConnectException || $response['error'] instanceof RingException) {
                     $connection->markDead();
                     $transport->connectionPool->scheduleCheck();
                     $neverRetry = isset($request['client']['never_retry']) ? $request['client']['never_retry'] : false;
                     $shouldRetry = $transport->shouldRetry($request);
                     if ($shouldRetry && !$neverRetry) {
                         return $transport->performRequest($request['http_method'], $request['uri'], [], $request['body'], $options);
                     }
                     // Due to the magic of futures, this will only be invoked if the final retry fails, since
                     // successful resolutions will go down the alternate `else` path the second time through
                     // the proxy
                     $this->throwCurlException($request, $response);
                 } else {
                     // Something went seriously wrong, bail
                     throw new TransportException($response['error']->getMessage());
                 }
             } else {
                 $connection->markAlive();
                 if (isset($response['body']) === true) {
                     $response['body'] = stream_get_contents($response['body']);
                 }
                 if ($response['status'] >= 400 && $response['status'] < 500) {
                     $ignore = isset($request['client']['ignore']) ? $request['client']['ignore'] : [];
                     $this->process4xxError($request, $response, $ignore);
                 } elseif ($response['status'] >= 500) {
                     $ignore = isset($request['client']['ignore']) ? $request['client']['ignore'] : [];
                     $this->process5xxError($request, $response, $ignore);
                 }
                 // No error, deserialize
                 $response['body'] = $this->serializer->deserialize($response['body'], $response['transfer_stats']);
             }
             $this->logRequestSuccess($request['http_method'], $response['effective_url'], $request['body'], $request['headers'], $response['status'], $response['body'], $response['transfer_stats']['total_time']);
             return isset($request['client']['verbose']) && $request['client']['verbose'] === true ? $response : $response['body'];
         });
         return $response;
     };
 }
Пример #4
0
 private function tryDeserializeError($response)
 {
     $error = $this->serializer->deserialize($response['body'], $response['transfer_stats']);
     if (is_array($error) === true) {
         // 2.0 structured exceptions
         if (isset($error['error']['reason']) === true) {
             $original = new ServerErrorResponseException($response['body'], $response['status']);
             $cause = $error['error']['reason'];
             $type = $error['error']['type'];
             return new ServerErrorResponseException("{$type}: {$cause}", $response['status'], $original);
         } elseif (isset($error['error']) === true) {
             // <2.0 semi-structured exceptions
             $original = new ServerErrorResponseException($response['body'], $response['status']);
             return new ServerErrorResponseException($error['error'], $response['status'], $original);
         }
         // <2.0 "i just blew up" nonstructured exception
         // $error is an array but we don't know the format, reuse the response body instead
         return new ServerErrorResponseException($response['body'], $response['status']);
     }
     // <2.0 "i just blew up" nonstructured exception
     return new ServerErrorResponseException($error, $response['status']);
 }