call api, handle error, return response

@param Message $req
@param String $method
@param String $uri
@param function $handler function($response, $bizerror, $common) create response oject or throw biz error exception
@return Message $result
954
public function callApi(Message $req, $method, $uri, $handler)
    {
        // check handler, php before 5.4 doesn't support Type Hinting of callable
        if (!is_callable($handler)) {
            throw new GeneralException("Can not find response handler.");
        }

        $data = [
            'json' => (object) $req->to_array(),
            'http_errors' => false,
        ];
        $response = $this->request($method, $uri, $data);
        $rawContent = $response->getBody()->getContents();

        $content = json_decode($rawContent, true);
        if (!$content) {
            throw new GeneralException("Response is not json data: " . $rawContent);
        }

        $statusCode = $response->getStatusCode();
        switch ($statusCode) {
            case 200:
                // happy path
                if (isset($content)) {
                    return $handler($content, "", "");
                } else {
                    throw new GeneralException("Cannot find response body: " . $rawContent);
                }
                break;
            case 400:
                // biz error
                if (isset($content)) {
                    return $handler("", $content, "");
                }
                throw new GeneralException("Cannot find Biz Error body: " . $rawContent);
                break;
            case 420:
                // common error
                if (isset($content)) {
                    return $handler("", "", $content);
                }
                throw new GeneralException("Cannot find Common Error body: " . $rawContent);
                break;
            case 500:
                // internal error
                throw new InternalServerErrorException("Internal server error: " . $rawContent);
                break;
        }
    }
157415
private function _call( $path, $method = 'GET', $params = array(), $retry = false ) {
			$this->_logger->entrance( $method . ':' . $path );

			if ( self::is_temporary_down() ) {
				$result = $this->get_temporary_unavailable_error();
			} else {
				$result = $this->_api->Api( $path, $method, $params );

				if ( null !== $result &&
				     isset( $result->error ) &&
				     isset( $result->error->code ) &&
				     'request_expired' === $result->error->code
				) {
					if ( ! $retry ) {
						$diff = isset( $result->error->timestamp ) ?
							( time() - strtotime( $result->error->timestamp ) ) :
							false;

						// Try to sync clock diff.
						if ( false !== $this->_sync_clock_diff( $diff ) ) {
							// Retry call with new synced clock.
							return $this->_call( $path, $method, $params, true );
						}
					}
				}
			}

			if ( $this->_logger->is_on() && self::is_api_error( $result ) ) {
				// Log API errors.
				$this->_logger->api_error( $result );
			}

			return $result;
		}
535078
public function sendAsync($method, $uri, $body = null, array $query = [], array $headers = [], array $options = [])
    {
        try {
            $this->validateMethod($method);
        } catch (\InvalidArgumentException $e) {
            return rejection_for($e);
        }

        $query = array_merge($this->getDefaultQuery(), $query);
        $headers = array_merge($this->getDefaultHeaders(), $headers);

        return $this->client->sendAsync($method, $uri, $body, $query, $headers, $options)->then(
            function (ResponseInterface $response) {
                $this->lastResponse = $response;

                $this->validateResponse($this->lastResponse);

                return $this->lastResponse;
            }
        );
    }
1365502
public function execute(Request $req = null, Response $res = null)
    {
        $auto = false;
        if (!isset($req)) {
            $auto = true;
            $req  = (new Request())->fromGlobals();
            $res  = (new Response($req));
        } else if (!isset($res)) {
            throw new App\Exception('You must pass a Response object when passing a Request object');
        }

        $this->param('req', $req)
             ->param('res', $res);
        try {
            $this->preExecute($req, $res);
            foreach ($this->_executables as $executable) {
                if ($executable instanceof Executable && !$executable instanceof App) {
                    $executable->preExecute($req, $res);
                }
            }
            $result = null;
            foreach ($this->_executables as $executable) {
                $result = call_user_func($executable instanceof Executable
                    ? [$executable, 'execute']
                    : $executable, $req, $res);
                if (isset($result)) {
                    break;
                }
            }
            if (!$result && !$this->_isSubapp) {
                if (isset($this->_failureHandler)) {
                    $result = call_user_func($this->_failureHandler, $req, $res);
                } else {
                    throw new App\Exception('Nothing successfully handled the request');
                }
            }
            foreach ($this->_executables as $executable) {
                if ($executable instanceof Executable && !$executable instanceof App) {
                    $executable->postExecute($req, $res);
                }
            }
            $this->postExecute($req, $res);
        } catch (\Exception $e) {
            if (isset($this->_errorHandler)) {
                $result = call_user_func($this->_errorHandler, $req, $res, $e);
            } else {
                throw $e;
            }
        }
        $this->param('req', null)
             ->param('res', null);
        
        if ($auto) {
            $res->toGlobals();
        } else {
            return $result;
        }
    }
1213052
public function remoteHttpCall($method, array $args)
    {
        $reqParams = [
            'version'   => static::$version,
            'args'      => array_values($args),
            'time'      => microtime(true),
            'handler'   => $this->handler,
            'construct' => $this->construct,
            'method'    => $method
        ];
        $sendData = [
            'data' => getInstance()->pack->pack($reqParams),
        ];
        $headers = [
            'X-RPC' => 1,
        ];

        /**
         * @var Client $client
         */
        $client = yield $this->getObject(Client::class)->goDnsLookup($this->host, $this->timeout, $headers);
        if (!$client) {
            throw new Exception($this->host . ' dns query failed');
        }

        $urlPath = '/' .$this->urlPath . '/' . $this->service . '/' . $this->handler . '/' . $this->method;
        if ($this->verb == 'POST') {
            $response = yield $client->goPost($urlPath, $sendData, $this->timeout);
        } else {
            $response = yield $client->goGet($urlPath, $sendData, $this->timeout);
        }

        if ($response && !empty($response['body']) && ($jsonRes = json_decode($response['body'], true))) {
            if ($response['statusCode'] !== 200) {
                $this->getContext()->getLog()->warning(dump($response, false, true));
                return false;
            } else {
                return $jsonRes;
            }
        } else {
            $this->getContext()->getLog()->warning(dump($response, false, true));
            return false;
        }
    }
1349582
public function call($api, $method = Request::METHOD_GET, array $data = [])
    {
        return $this->checkException($this->callHttpMethod($this->normalizeUri($api), $method, $data));
    }
413364
private function request($method, $uri, $body = array())
    {
        try {
            $res = $this->client->sendRequest($method, $uri, $body);
            return json_decode($res->getBody(), true);
        } catch(FacebookSDKException $e){
            /*
             * If the session expired, then we must request a new token with the
             * refresh token.
             */
//            if($e->getCode() == '190'){
//                $this->refreshToken($method, $uri, $body);
//            } else {
                throw new ExternalApiException($e->getMessage(), $e->getCode(), $e);
//            }
        }
    }
218825
private function request($method, $uri, $data = [])
    {
        $uri = $this->getUri($uri);

        $headers = [];

        // Basic Auth
        $credentials = $this->key.':'.$this->password;

        // User Agent
        $agent = sprintf("%s %s", Client::NAME, Client::VERSION);

        $ch = curl_init();

        if (strtoupper($method) === 'GET' && !empty($data)) {
            $queryString = http_build_query($data);
            $uri .= '?'.$queryString;
        }

        $options = [
            CURLOPT_URL => $uri,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER => true,
            CURLOPT_USERAGENT => $agent,
            CURLOPT_USERPWD => $credentials,
            CURLOPT_TIMEOUT => 60,
        ];

        if (strtoupper($method) === 'POST') {
            $jsonData = json_encode($data);

            $headers[] = 'Content-Type: application/json';
            $headers[] = 'Content-Length: '.strlen($jsonData);

            $options[CURLOPT_CUSTOMREQUEST] = 'POST';
            $options[CURLOPT_POSTFIELDS] = $jsonData;
        }

        if (isset($this->version) && is_numeric($this->version)) {
            $headers[] = 'X-EWAY-APIVERSION: '.$this->version;
        }

        $options[CURLOPT_HTTPHEADER] = $headers;

        curl_setopt_array($ch, $options);

        $rawResponse = curl_exec($ch);

        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);

        if (curl_errno($ch)) {
            $responseError = curl_error($ch);
            $responseBody = '';
        } else {
            $responseError = '';
            $responseBody = $this->parseResponse($rawResponse, $headerSize);
        }

        $response = new Response($statusCode, $responseBody, $responseError);

        curl_close($ch);

        return $response;
    }
1010379
protected function request($url, $method, $data = null)
    {
        $this->testLogin();
        try {
            $response = $this->transport->send(
                $url, $method, $data, array(
                'Content-Type: ' . $this->mapper->getContentType(),
                )
            );
        } catch (HttpStatusException $e) {
            $message = $e->getMessage();
            if ($e->getCode() == 403 || $e->getCode() == 422) {
                $this->errors = $this->mapper->mapFromStorage($this->transport->getLastResponse());
                if ($this->errors instanceof ErrorArray && count($this->errors) > 0) {
                    $message .= PHP_EOL . 'Errors:' . PHP_EOL . $this->errors;
                }
            }

            if (self::$debug) {
                printf(
                    'Url: %s' . PHP_EOL . 'Method: %s' . PHP_EOL . 'Data: %s', $url, $method, $data
                );
            }

            switch ($e->getCode()) {
                case 401:
                    throw new NotLoggedInException($message, 0, $e);
                    break;
                case 403:
                    throw new ForbiddenException($message, 0, $e);
                    break;
                case 404:
                    throw new NotFoundException($message, 0, $e);
                    break;
                case 406:
                case 422:
                    throw new NotValidException($message, 0, $e);
                    break;
                default:
                    $message = 'Unknown error; check https://github.com/bluetools/moneybird_php_api/wiki/Common-errors';
                // no break
                case 500:
                case 501:
                    throw new ServerErrorException($message, 0, $e);
                    break;
            }
        }

        return $response;
    }
1213209
protected function makeRequest($method, $uri, $parameters = [], $cookies = [], $files = [])
    {
        $uri = $this->prepareUrlForRequest($uri);

        $this->call($method, $uri, $parameters, $cookies, $files);

        $this->clearInputs()->followRedirects()->assertPageLoaded($uri);

        $this->currentUri = $this->app->make('request')->fullUrl();

        $this->crawler = new Crawler($this->response->getContent(), $this->currentUri);

        return $this;
    }
743128
public function resolve(Router $router, $uri, $method)
	{
		// get all register routes with the same request method
		$routes = $router->getRoutesByMethod($method);
		// remove trailing and leading slash
		$requestedUri = trim(preg_replace('/\?.*/', '', $uri), '/');
		// loop trough the posible routes
		foreach ($routes as $route) {
			$matches = array();

			// if the requested route matches one of the defined routes
			if ($route->getUrl() === $requestedUri || preg_match('~^'.$route->getUrl().'$~', $requestedUri, $matches)) {
				$argumentArray = array();
				$arguments = $this->getArguments($matches);

				// check if there route has arguments
				if (is_array($route->getArguments()) && count($route->getArguments()) > 0) {
					// loop trough all the arguments
					foreach ($route->getArguments() as $key => $argument) {
						// if the argument exists set the value
						if (isset($arguments[$key])) {
							$argumentArray[$argument] = $arguments[$key];
						} else {
							// setting the value to null should only occure when we use an optional parameter
							$argumentArray[$argument] = null;
						}
					}
				}

				return [
					'code' => Route::STATUS_FOUND,
					'handler' => $route->getAction(),
					'arguments' => $argumentArray
				];
			}
		}

		return [
			'code' => Route::STATUS_NOT_FOUND,
			'handler' => null,
			'arguments' => []
		];
	}
968972
private function sendRequest(string $method, string $uri, array $query = [], array $body = []) : array {
        $uri = sprintf('%s%s', $this->baseUrl, ltrim($uri, '/'));

        $options = [
            'headers' => [
                'Authorization' => (string) $this->authentication
            ],
            'http_errors' => false
        ];

        if (! empty($query)) {
            $options['query'] = $query;
        }

        if (! empty($body)) {
            $options['json'] = $body;
        }

        $response = $this->client->request(
            $method,
            $uri,
            $options
        );

        $json = json_decode((string) $response->getBody(), true);
        if ($json === null) {
            if ($this->throwsExceptions) {
                throw new SDKError();
            }

            return [(string) $response->getBody()];
        }

        if (($json['status'] === false) && ($this->throwsExceptions)) {
            throw new SDKException(
                $json['error']['message'],
                $json['error']['type'],
                $json['error']['link']
            );
        }

        return $json;
    }
1083601
protected function handleRequest($method, $resource, $options)
    {
        $response = null;
        try
        {
            $response = $this->handleResponse($this->getHttpClient()->request($method, $resource, $options));
        }
        catch (RequestException $e)
        {
            $this->handleException($e);
        }

        return $response;
    }
144034
private function jsonCall($method, $uri, $body = null)
    {
        $jsonBody = null;

        if (null !== $body) {
            $jsonBody = json_encode($body);
        }

        $request = new Request($method, $uri, ['Content-Type' => 'application/json'], $jsonBody);
        $response = $this->guzzle->send($request);
        $this->lastResponse = $response;

        self::checkResponse($response);

        return json_decode($response->getBody());
    }
12976
private function _request($method, $url, array $options) {
		try {
			$response = $this->httpClient->{$method}($url, $options);
		} catch(ClientException $e) {
			$response = $e->getResponse();
		} catch(ConnectException $e) {
			$this->_throwServerError($e);
		} catch (RequestException $e) {
			$this->_throwServerError($e);
		}

		return $response;
	}
231565
public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
    {
        $this->currentUri = $this->prepareUrlForRequest($uri);

        $symfonyRequest = SymfonyRequest::create(
            $this->currentUri, $method, $parameters,
            $cookies, $files, $server, $content
        );

        $response = $this->app->prepareResponse(
            $this->app->handle(Request::createFromBase($symfonyRequest))
        );
        $this->response = $this->createTestResponse($response);

        return $this->response;
    }
271119
public function request($method, $uri, array $data = array())
    {
        $path = $this->path() . '/' . trim($uri, '/');

        $session = curl_init();

        // Curious as why i have to do this
        if ($method === 'PUT') {
            curl_setopt($session, CURLOPT_POSTFIELDS, http_build_query($data));
        } else {
            $path .= '?' . http_build_query($data);
        }

        curl_setopt($session, CURLOPT_HEADER, true);
        curl_setopt($session, CURLOPT_HTTPHEADER, $this->defaultHeaders());
        curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($session, CURLOPT_POST, $method !== 'GET');

        curl_setopt($session, CURLOPT_URL, $path);
        curl_setopt($session, CURLOPT_CUSTOMREQUEST, $method);
        $response = curl_exec($session);
        $statusCode = curl_getinfo($session, CURLINFO_HTTP_CODE);
        $headerSize = curl_getinfo($session, CURLINFO_HEADER_SIZE);
        $body = substr($response, $headerSize);

        if ($statusCode !== 200) {
            throw new InvalidRequest($body);
        }

        curl_close($session);

        return json_decode($body, true);
    }