Skip to content

Commit

Permalink
Merge pull request #31 from answear/throw-response-timeout
Browse files Browse the repository at this point in the history
Throw response timeout
  • Loading branch information
lukasz-falda authored Dec 15, 2020
2 parents f272fba + 0ecd91b commit 6330ff1
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 101 deletions.
53 changes: 48 additions & 5 deletions src/LuigisBoxBundle/Service/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,79 @@

namespace Answear\LuigisBoxBundle\Service;

use Answear\LuigisBoxBundle\Exception\BadRequestException;
use Answear\LuigisBoxBundle\Exception\ServiceUnavailableException;
use Answear\LuigisBoxBundle\Exception\TooManyItemsException;
use Answear\LuigisBoxBundle\Exception\TooManyRequestsException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\HttpFoundation\Response;

class Client
{
/**
* @var ConfigProvider
*/
private $configProvider;
/**
* @var \GuzzleHttp\Client
*/
private $client;

public function __construct(ConfigProvider $configProvider)
public function __construct(ConfigProvider $configProvider, ?\GuzzleHttp\Client $client = null)
{
$this->configProvider = $configProvider;
$this->client = $client ?? $this->getGuzzleClient();
}

/**
* @throws GuzzleException
* @throws BadRequestException
* @throws TooManyRequestsException
* @throws TooManyItemsException
* @throws ServiceUnavailableException
*/
public function request(Request $request): ResponseInterface
{
try {
$response = $this->client->send($request);

$this->throwOnResponseErrors($request, $response);
} catch (GuzzleException $e) {
throw new ServiceUnavailableException($e->getMessage(), $e->getCode(), $e);
}

return $response;
}

private function throwOnResponseErrors(Request $request, ResponseInterface $response): void
{
if (Response::HTTP_BAD_REQUEST === $response->getStatusCode()) {
throw new BadRequestException($response, $request);
}
if (Response::HTTP_TOO_MANY_REQUESTS === $response->getStatusCode()) {
$retryAfter = $response->getHeader('Retry-After');
$retryAfter = reset($retryAfter);
throw new TooManyRequestsException((int) $retryAfter, $response);
}
if (Response::HTTP_REQUEST_ENTITY_TOO_LARGE === $response->getStatusCode()) {
throw new TooManyItemsException(null, null, $response);
}
if (Response::HTTP_BAD_REQUEST <= $response->getStatusCode()) {
throw RequestException::create($request, $response);
}
}

private function getGuzzleClient(): \GuzzleHttp\Client
{
$options = [
RequestOptions::TIMEOUT => $this->configProvider->getRequestTimeout(),
RequestOptions::CONNECT_TIMEOUT => $this->configProvider->getConnectionTimeout(),
RequestOptions::HTTP_ERRORS => false,
];

$client = new \GuzzleHttp\Client($options);

return $client->send($request);
return new \GuzzleHttp\Client($options);
}
}
89 changes: 29 additions & 60 deletions src/LuigisBoxBundle/Service/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
use Answear\LuigisBoxBundle\ValueObject\ContentUpdate;
use Answear\LuigisBoxBundle\ValueObject\ContentUpdateCollection;
use Answear\LuigisBoxBundle\ValueObject\PartialContentUpdate;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\HttpFoundation\Response;
use Webmozart\Assert\Assert;

class Request implements RequestInterface
Expand Down Expand Up @@ -62,6 +60,7 @@ public function __construct(
}

/**
* @throws BadRequestException
* @throws TooManyRequestsException
* @throws TooManyItemsException
* @throws ServiceUnavailableException
Expand All @@ -75,19 +74,16 @@ public function contentUpdate(ContentUpdateCollection $objects): ApiResponse
throw new TooManyItemsException(\count($objects), self::CONTENT_UPDATE_OBJECTS_LIMIT);
}

try {
$request = $this->contentUpdateFactory->prepareRequest($objects);

return new ApiResponse(
\count($objects),
$this->handleResponse($request, $this->client->request($request))
);
} catch (GuzzleException $e) {
throw new ServiceUnavailableException($e->getMessage(), $e->getCode(), $e);
}
$request = $this->contentUpdateFactory->prepareRequest($objects);

return new ApiResponse(
\count($objects),
$this->handleResponse($request, $this->client->request($request))
);
}

/**
* @throws BadRequestException
* @throws TooManyRequestsException
* @throws TooManyItemsException
* @throws ServiceUnavailableException
Expand All @@ -101,58 +97,48 @@ public function partialContentUpdate(ContentUpdateCollection $objects): ApiRespo
throw new TooManyItemsException(\count($objects), self::PARTIAL_CONTENT_UPDATE_OBJECTS_LIMIT);
}

try {
$request = $this->partialContentUpdateFactory->prepareRequest($objects);

return new ApiResponse(
\count($objects),
$this->handleResponse($request, $this->client->request($request))
);
} catch (GuzzleException $e) {
throw new ServiceUnavailableException($e->getMessage(), $e->getCode(), $e);
}
$request = $this->partialContentUpdateFactory->prepareRequest($objects);

return new ApiResponse(
\count($objects),
$this->handleResponse($request, $this->client->request($request))
);
}

/**
* @throws BadRequestException
* @throws TooManyRequestsException
* @throws TooManyItemsException
* @throws ServiceUnavailableException
* @throws MalformedResponseException
*/
public function contentRemoval(ContentRemovalCollection $objects): ApiResponse
{
try {
$request = $this->contentRemovalFactory->prepareRequest($objects);

return new ApiResponse(
\count($objects),
$this->handleResponse($request, $this->client->request($request))
);
} catch (GuzzleException $e) {
throw new ServiceUnavailableException($e->getMessage(), $e->getCode(), $e);
}
$request = $this->contentRemovalFactory->prepareRequest($objects);

return new ApiResponse(
\count($objects),
$this->handleResponse($request, $this->client->request($request))
);
}

/**
* @param ContentAvailabilityCollection|ContentAvailability $object
*
* @throws BadRequestException
* @throws TooManyRequestsException
* @throws TooManyItemsException
* @throws ServiceUnavailableException
* @throws MalformedResponseException
* @throws TooManyRequestsException
*/
public function changeAvailability($object): ApiResponse
{
try {
$request = $this->partialContentUpdateFactory->prepareRequestForAvailability($object);

return new ApiResponse(
$object instanceof ContentAvailabilityCollection ? \count($object) : 1,
$this->handleResponse($request, $this->client->request($request))
);
} catch (GuzzleException $e) {
throw new ServiceUnavailableException($e->getMessage(), $e->getCode(), $e);
}
$request = $this->partialContentUpdateFactory->prepareRequestForAvailability($object);

return new ApiResponse(
$object instanceof ContentAvailabilityCollection ? \count($object) : 1,
$this->handleResponse($request, $this->client->request($request))
);
}

public static function getContentUpdateLimit(): int
Expand All @@ -166,27 +152,10 @@ public static function getPartialContentUpdateLimit(): int
}

/**
* @throws BadRequestException
* @throws TooManyRequestsException
* @throws TooManyItemsException
* @throws MalformedResponseException
*/
private function handleResponse(\GuzzleHttp\Psr7\Request $request, ResponseInterface $response): array
{
if (Response::HTTP_BAD_REQUEST === $response->getStatusCode()) {
throw new BadRequestException($response, $request);
}

if (Response::HTTP_TOO_MANY_REQUESTS === $response->getStatusCode()) {
$retryAfter = $response->getHeader('Retry-After');
$retryAfter = reset($retryAfter);
throw new TooManyRequestsException((int) $retryAfter, $response);
}

if (Response::HTTP_REQUEST_ENTITY_TOO_LARGE === $response->getStatusCode()) {
throw new TooManyItemsException(null, null, $response);
}

if ($response->getBody()->isSeekable()) {
$response->getBody()->rewind();
}
Expand Down
26 changes: 12 additions & 14 deletions src/LuigisBoxBundle/Service/SearchRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
use Answear\LuigisBoxBundle\Exception\BadRequestException;
use Answear\LuigisBoxBundle\Exception\MalformedResponseException;
use Answear\LuigisBoxBundle\Exception\ServiceUnavailableException;
use Answear\LuigisBoxBundle\Exception\TooManyItemsException;
use Answear\LuigisBoxBundle\Exception\TooManyRequestsException;
use Answear\LuigisBoxBundle\Factory\SearchFactory;
use Answear\LuigisBoxBundle\Response\SearchResponse;
use Answear\LuigisBoxBundle\ValueObject\SearchUrlBuilder;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\HttpFoundation\Response;
use Webmozart\Assert\Assert;
Expand All @@ -36,29 +37,26 @@ public function __construct(
}

/**
* @throws BadRequestException
* @throws TooManyRequestsException
* @throws TooManyItemsException
* @throws ServiceUnavailableException
* @throws MalformedResponseException
* @throws BadRequestException
*/
public function search(SearchUrlBuilder $searchUrlBuilder): SearchResponse
{
try {
$request = $this->searchFactory->prepareRequest($searchUrlBuilder);
$request = $this->searchFactory->prepareRequest($searchUrlBuilder);

$url = $searchUrlBuilder->toUrlQuery();
Assert::notEmpty($url);
$url = $searchUrlBuilder->toUrlQuery();
Assert::notEmpty($url);

return new SearchResponse(
$url . '&v=' . $this->getUniqueStamp(),
$this->handleResponse($request, $this->client->request($request))
);
} catch (GuzzleException $e) {
throw new ServiceUnavailableException($e->getMessage(), $e->getCode(), $e);
}
return new SearchResponse(
$url . '&v=' . $this->getUniqueStamp(),
$this->handleResponse($request, $this->client->request($request))
);
}

/**
* @throws BadRequestException
* @throws MalformedResponseException
*/
private function handleResponse(\GuzzleHttp\Psr7\Request $request, ResponseInterface $response): array
Expand Down
12 changes: 12 additions & 0 deletions src/LuigisBoxBundle/Service/SearchRequestInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,22 @@

namespace Answear\LuigisBoxBundle\Service;

use Answear\LuigisBoxBundle\Exception\BadRequestException;
use Answear\LuigisBoxBundle\Exception\MalformedResponseException;
use Answear\LuigisBoxBundle\Exception\ServiceUnavailableException;
use Answear\LuigisBoxBundle\Exception\TooManyItemsException;
use Answear\LuigisBoxBundle\Exception\TooManyRequestsException;
use Answear\LuigisBoxBundle\Response\SearchResponse;
use Answear\LuigisBoxBundle\ValueObject\SearchUrlBuilder;

interface SearchRequestInterface
{
/**
* @throws BadRequestException
* @throws TooManyRequestsException
* @throws TooManyItemsException
* @throws ServiceUnavailableException
* @throws MalformedResponseException
*/
public function search(SearchUrlBuilder $searchUrlBuilder): SearchResponse;
}
30 changes: 16 additions & 14 deletions src/LuigisBoxBundle/Service/UpdateByQueryRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
use Answear\LuigisBoxBundle\Exception\BadRequestException;
use Answear\LuigisBoxBundle\Exception\MalformedResponseException;
use Answear\LuigisBoxBundle\Exception\ServiceUnavailableException;
use Answear\LuigisBoxBundle\Exception\TooManyItemsException;
use Answear\LuigisBoxBundle\Exception\TooManyRequestsException;
use Answear\LuigisBoxBundle\Factory\UpdateByRequestFactory;
use Answear\LuigisBoxBundle\Factory\UpdateByRequestStatusFactory;
use Answear\LuigisBoxBundle\Response\UpdateByQuery\UpdateByQueryResponse;
use Answear\LuigisBoxBundle\Response\UpdateByQuery\UpdateByQueryStatusResponse;
use Answear\LuigisBoxBundle\ValueObject\UpdateByQuery;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\HttpFoundation\Response;
use Webmozart\Assert\Assert;
Expand Down Expand Up @@ -46,29 +47,30 @@ public function __construct(

/**
* @throws BadRequestException
* @throws MalformedResponseException
* @throws TooManyRequestsException
* @throws TooManyItemsException
* @throws ServiceUnavailableException
* @throws MalformedResponseException
*/
public function update(UpdateByQuery $updateByQuery): UpdateByQueryResponse
{
try {
$request = $this->factory->prepareRequest($updateByQuery);
$request = $this->factory->prepareRequest($updateByQuery);

return new UpdateByQueryResponse($this->handleResponse($request, $this->client->request($request)));
} catch (GuzzleException $e) {
throw new ServiceUnavailableException($e->getMessage(), $e->getCode(), $e);
}
return new UpdateByQueryResponse($this->handleResponse($request, $this->client->request($request)));
}

/**
* @throws BadRequestException
* @throws TooManyRequestsException
* @throws TooManyItemsException
* @throws ServiceUnavailableException
* @throws MalformedResponseException
*/
public function getStatus(int $jobId): UpdateByQueryStatusResponse
{
try {
$request = $this->statusFactory->prepareRequest($jobId);
$request = $this->statusFactory->prepareRequest($jobId);

return new UpdateByQueryStatusResponse($this->handleResponse($request, $this->client->request($request)));
} catch (GuzzleException $e) {
throw new ServiceUnavailableException($e->getMessage(), $e->getCode(), $e);
}
return new UpdateByQueryStatusResponse($this->handleResponse($request, $this->client->request($request)));
}

/**
Expand Down
Loading

0 comments on commit 6330ff1

Please sign in to comment.