Skip to content

Commit

Permalink
distinct exception type thrown when best available objects not found (#…
Browse files Browse the repository at this point in the history
…142)

* refactoring

* throw new exception type when no best available objects have been found, instead of the generic SeatsioException

* refactoring - moved BestAvailableObjectsNotFoundException to root Seatsio namespace

* refactoring - removed unused $response constructor parameter

* refactoring - rename
  • Loading branch information
bverbeken authored Jan 3, 2025
1 parent 95ca915 commit 7e41272
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 16 deletions.
14 changes: 14 additions & 0 deletions src/BestAvailableObjectsNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Seatsio;


use Psr\Http\Message\RequestInterface;

class BestAvailableObjectsNotFoundException extends SeatsioException
{
public function __construct(RequestInterface $request, array $parsedResponse, string $message)
{
parent::__construct($request, $parsedResponse, $message);
}
}
5 changes: 2 additions & 3 deletions src/RateLimitExceededException.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
namespace Seatsio;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

class RateLimitExceededException extends SeatsioException
{
public function __construct(RequestInterface $request, ResponseInterface $response)
public function __construct(RequestInterface $request, array $parsedResponse, string $message)
{
parent::__construct($request, $response);
parent::__construct($request, $parsedResponse, $message);
}
}
5 changes: 1 addition & 4 deletions src/SeatsioClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,7 @@ function (ResponseInterface $response) use ($request, $handler) {
if ($code < 400) {
return $response;
}
if ($code == 429) {
throw new RateLimitExceededException($request, $response);
}
throw new SeatsioException($request, $response);
throw SeatsioException::from($request, $response);
}
);
};
Expand Down
42 changes: 34 additions & 8 deletions src/SeatsioException.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,24 @@ class SeatsioException extends RuntimeException
*/
public $requestId;

public function __construct(RequestInterface $request, ResponseInterface $response)
public static function from(RequestInterface $request, ResponseInterface $response): SeatsioException
{
$info = self::extractInfo($response);
$requestId = $info['requestId'];
parent::__construct(self::message($request, $response, $info['messages']));
$this->errors = $info['errors'];
$this->requestId = $requestId;
$code = $response->getStatusCode();
$parsedResponse = self::extractInfo($response);
$message = self::message($request, $response, $parsedResponse['messages']);
if ($code == 429) {
return new RateLimitExceededException($request, $parsedResponse, $message);
} else if (self::isBestAvailableObjectsNotFound($parsedResponse['errors'])) {
throw new BestAvailableObjectsNotFoundException($request, $parsedResponse, $message);
}
return new SeatsioException($request, $parsedResponse, $message);
}

public function __construct(RequestInterface $request, array $parsedResponse, string $message)
{
parent::__construct($message);
$this->errors = $parsedResponse['errors'];
$this->requestId = $parsedResponse['requestId'];
}

private static function message($request, $response, $messages)
Expand All @@ -45,15 +56,30 @@ private static function message($request, $response, $messages)
}
}

private static function extractInfo($response)
private static function extractInfo($response): array
{
$contentType = $response->getHeaderLine("content-type");
if (strpos($contentType, 'application/json') !== false) {
if (str_contains($contentType, 'application/json')) {
$json = GuzzleResponseDecoder::decodeToObject($response);
$mapper = SeatsioJsonMapper::create();
$errors = $mapper->mapArray($json->errors, array(), 'Seatsio\ApiError');
return ["messages" => $json->messages, "errors" => $errors, "requestId" => $json->requestId ?? null];
}
return ["messages" => [], "errors" => [], "requestId" => null];
}

private static function isBestAvailableObjectsNotFound($errors): bool
{
if (!is_array($errors) || empty($errors)) {
return false;
}
foreach ($errors as $error) {
if (is_object($error) && property_exists($error, 'code')) {
if ($error->code === 'BEST_AVAILABLE_OBJECTS_NOT_FOUND') {
return true;
}
}
}
return false;
}
}
30 changes: 30 additions & 0 deletions tests/Events/ChangeBestAvailableObjectStatusTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace Seatsio\Events;

use Seatsio\BestAvailableObjectsNotFoundException;
use Seatsio\Common\IDs;
use Seatsio\SeatsioClientTest;
use Seatsio\SeatsioException;

class ChangeBestAvailableObjectStatusTest extends SeatsioClientTest
{
Expand Down Expand Up @@ -203,4 +205,32 @@ public function accessibleSeats()
self::assertTrue($bestAvailableObjects->nextToEachOther);
self::assertEquals(["A-6", "A-7", "A-8"], $bestAvailableObjects->objects);
}

public function testNotFoundThrowsBestAvailableObjectsNotFoundException()
{
$chartKey = $this->createTestChart();
$event = $this->seatsioClient->events->create($chartKey);

try
{
$this->seatsioClient->events->changeBestAvailableObjectStatus($event->key, (new BestAvailableParams())->setNumber(3000), "lolzor");
self::fail("expected exception");
} catch (BestAvailableObjectsNotFoundException $exception) {
self::assertInstanceOf(BestAvailableObjectsNotFoundException::class, $exception);
self::assertEquals("Best available objects not found", $exception->getMessage());
}

}

public function testNormalSeatsioExceptionIfEventNotFound()
{
try
{
$this->seatsioClient->events->changeBestAvailableObjectStatus("unexistingEvent", (new BestAvailableParams())->setNumber(3), "lolzor");
self::fail("expected exception");
} catch (SeatsioException $exception) {
self::assertNotInstanceOf(BestAvailableObjectsNotFoundException::class, $exception);
}

}
}
2 changes: 1 addition & 1 deletion tests/SeatsioExceptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function testCanInstantiateSeatsioExceptionWithoutRequestId()
["Content-Type" => "application/json"],
"{\"errors\": [], \"messages\":[]}"
);
$exception = new SeatsioException($request, $response);
$exception = SeatsioException::from($request, $response);
self::assertNull($exception->requestId);
self::assertStringStartsWith("GET http://dummy.uri resulted in a `400 Bad Request` response.", $exception->getMessage());
}
Expand Down

0 comments on commit 7e41272

Please sign in to comment.