From 6cbe9cbe142d14149424a285775e46931a584a03 Mon Sep 17 00:00:00 2001 From: Andrii Vasyliev Date: Fri, 20 Jan 2017 19:58:09 +0000 Subject: [PATCH] fixed error handling --- src/Command.php | 8 ++-- src/Connection.php | 104 +++++++++++---------------------------------- src/Request.php | 42 ++++++++++++------ 3 files changed, 58 insertions(+), 96 deletions(-) diff --git a/src/Command.php b/src/Command.php index 7fe418c..51e7932 100644 --- a/src/Command.php +++ b/src/Command.php @@ -38,7 +38,7 @@ public function setRequest(Request $request) * Sends a request to retrieve data. * In API this could be get, search or list request. * @throws ErrorResponseException - * @return mixed + * @return mixed response data */ public function search() { @@ -86,7 +86,7 @@ public function delete($table, $condition, array $options = []) * @param string $table * @param mixed $body * @param array $options - * @return mixed + * @return mixed response data */ public function perform($action, $table, $body = [], array $options = []) { @@ -100,7 +100,7 @@ public function perform($action, $table, $body = [], array $options = []) * Executes the request. * @param string $url URL * @param mixed $body request parameters - * @return mixed + * @return mixed response data */ public function execute() { @@ -110,7 +110,7 @@ public function execute() $response = $this->db->send($this->request); Yii::endProfile($profile, $category); - return $response->getData(); + return $this->db->checkResponse($response); } public static function getProfileCategory() diff --git a/src/Connection.php b/src/Connection.php index ca910f0..ffc5a6f 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -182,67 +182,6 @@ public function createQueryBuilder() } - /** - * Make request and check for error. - * @param string $url URL - * @param array $query query options (GET parameters) - * @param string $body request body (POST parameters) - * @param bool $raw Do not try to decode data, event when response is decodeable (JSON). Defaults to `false` - * @throws HiArtException - * @throws \yii\base\InvalidConfigException - * @return mixed response - */ - public function makeRequest($method, $url, $query = [], $body = null, $raw = false) - { - $result = $this->handleRequest($method, $this->prepareUrl($url, $query), $body, $raw); - - return $this->checkResponse($result, $url, $query); - } - - /** - * Creates URL by joining path part and query options. - * @param mixed $path path - * @param array $query query options - * @return array - */ - private function prepareUrl($path, array $query = []) - { - $url = $path; - $query = array_merge($this->getAuth(), $query); - if (!empty($query)) { - $url .= (strpos($url, '?') === false ? '?' : '&') . http_build_query($query); - } - - return $url; - } - - /** - * Handles the request with handler. - * Returns array or raw response content, if $raw is true. - * - * @param string $method POST, GET, etc - * @param string $url the URL for request, not including proto and site - * @param array|string $body the request body. When array - will be sent as POST params, otherwise - as RAW body. - * @param bool $raw Do not try to decode data, event when response is decodeable (JSON). Defaults to `false` - * @return array|string - */ - protected function handleRequest($method, $url, $body = null, $raw = false) - { - $method = strtoupper($method); - $profile = $method . ' ' . $url . '#' . (is_array($body) ? http_build_query($body) : $body); - $options = [(is_array($body) ? 'form_params' : 'body') => $body]; - Yii::beginProfile($profile, __METHOD__); - $response = $this->getHandler()->request($method, $url, $options); - Yii::endProfile($profile, __METHOD__); - - $res = $response->getBody()->getContents(); - if (!$raw && preg_grep('|application/json|i', $response->getHeader('Content-Type'))) { - $res = Json::decode($res); - } - - return $res; - } - /** * Returns the request handler (Guzzle client for the moment). * Creates and setups handler if not set. @@ -317,46 +256,53 @@ protected function decodeErrorBody($body) /** * Setter for errorChecker. - * @param Closure|array $value + * @param Closure $checker */ - public function setErrorChecker($value) + public function setErrorChecker($checker) { - $this->_errorChecker = $value; + $this->_errorChecker = $checker; } /** * Checks response with checkError method and raises exception if error. - * @param array $response response data from API - * @param string $url request URL - * @param array $options request data + * @param Response $response response data from API * @throws ErrorResponseException - * @return array + * @return mixed response data */ - protected function checkResponse($response, $url, $options) + public function checkResponse(Response $response) { $error = $this->checkError($response); - if (isset($error)) { + if ($error) { throw new ErrorResponseException($error, [ - 'requestUrl' => $url, - 'request' => $options, - 'response' => $response, + 'request' => $response->getRequest()->getParts(), + 'response' => $response->getData(), ]); } - return $response; + return $response->getData(); } /** - * Checks response with errorChecker callback and returns not null if error. - * @param array $response response data from API - * @return null|string + * Checks response with errorChecker callback and returns error text if error. + * @param Response $response + * @return string|false error text or false */ - public function checkError($response) + public function checkError(Response $response) { if (isset($this->_errorChecker)) { return call_user_func($this->_errorChecker, $response); + } else { + return $this->isError($response); } + } - return null; + /** + * Default error checker. TODO check something in response? + * @param Response $response + * @return bool + */ + public function isError(Response $response) + { + return false; } } diff --git a/src/Request.php b/src/Request.php index 8955c2f..097907c 100644 --- a/src/Request.php +++ b/src/Request.php @@ -21,6 +21,8 @@ class Request implements \Serializable */ protected $worker; + protected $workerClass = Worker::class; + /** * @var Query */ @@ -40,6 +42,8 @@ class Request implements \Serializable protected $body; protected $version; + protected $parts = []; + public function __construct(QueryBuilder $builder, Query $query) { $this->builder = $builder; @@ -76,6 +80,17 @@ public function getVersion() return $this->version; } + /** + * @return Query + */ + public function getQuery() + { + return $this->query; + } + + /** + * @return Worker + */ public function getWorker() { if ($this->worker === null) { @@ -88,11 +103,6 @@ public function getWorker() return $this->worker; } - public function getQuery() - { - return $this->query; - } - protected function updateFromQuery() { $this->builder->prepare($this->query); @@ -110,7 +120,7 @@ protected function updateFromQuery() protected function createWorker() { - return new Worker($this->method, $this->uri, $this->headers, $this->body, $this->version); + return new $this->workerClass($this->method, $this->uri, $this->headers, $this->body, $this->version); } protected function buildDbname() @@ -174,13 +184,7 @@ protected function buildProtocolVersion() public function serialize() { - $this->getWorker(); - $data = []; - foreach (['dbname', 'method', 'uri', 'headers', 'body', 'version'] as $key) { - $data[$key] = $this->{$key}; - } - - return serialize($data); + return serialize($this->getParts()); } public function unserialize($string) @@ -190,6 +194,18 @@ public function unserialize($string) } } + public function getParts() + { + if (empty($this->parts)) { + $this->getWorker(); + foreach (['dbname', 'method', 'uri', 'headers', 'body', 'version'] as $key) { + $this->parts[$key] = $this->{$key}; + } + } + + return $this->parts; + } + public function isRaw() { return !empty($this->query->options['raw']);