mirror of
https://github.com/anikeen-com/id.git
synced 2026-11-04 22:59:41 +00:00
Throw ApiException for requests with the user's token too
Requests with the user's token threw a bare ResourceException with a message like "… for resource [Anikeen\Id\Resources\Order]" and no error code, while app requests threw ApiException. Both throw ApiException now: status (also getCode()), Anikeen ID's error code and message, isNotFound(), isConflict(), isTemporary(). Failed lists throw CollectionException, now a subclass of ApiException. A request without a response (connection refused, timeout) throws ApiException with status 0 instead of a Guzzle exception. ApiException extends ResourceException, so existing catch blocks keep working. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a4345e72ec
commit
57ce0b4a79
8 files changed
+196
-33
No files matched your search
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Anikeen\Id\Exceptions;
|
||||
|
||||
use Anikeen\Id\Result;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
@@ -19,6 +20,30 @@ class ApiException extends ResourceException
|
||||
parent::__construct($message, $status, $previous);
|
||||
}
|
||||
|
||||
/**
|
||||
* The exception for a failed request: Anikeen ID's message and error code, the HTTP status
|
||||
* (0 when there was no response).
|
||||
*/
|
||||
public static function fromResult(Result $result): static
|
||||
{
|
||||
$body = is_object($result->data) ? $result->data : null;
|
||||
|
||||
return new static(
|
||||
rtrim((string) ($body->message ?? $result->error()), '.'),
|
||||
$result->response()?->getStatusCode() ?? 0,
|
||||
$body->error ?? null,
|
||||
$result->exception,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The exception for a request that got no response (network error, timeout).
|
||||
*/
|
||||
public static function unreachable(Throwable $previous): static
|
||||
{
|
||||
return new static(sprintf('Anikeen ID is not reachable: %s', $previous->getMessage()), 0, null, $previous);
|
||||
}
|
||||
|
||||
public function isNotFound(): bool
|
||||
{
|
||||
return $this->status === 404;
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace Anikeen\Id\Exceptions;
|
||||
|
||||
use Anikeen\Id\Result;
|
||||
use Exception;
|
||||
|
||||
class CollectionException extends Exception
|
||||
/**
|
||||
* A list request failed. Like ApiException it carries the HTTP status (also as getCode()) and
|
||||
* Anikeen ID's error code.
|
||||
*/
|
||||
class CollectionException extends ApiException
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ use Anikeen\Id\Exceptions\CollectionException;
|
||||
use Anikeen\Id\Helpers\Paginator;
|
||||
use Anikeen\Id\Result;
|
||||
use Closure;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use JsonSerializable;
|
||||
use Throwable;
|
||||
@@ -34,10 +35,15 @@ abstract class BaseCollection implements JsonSerializable
|
||||
*/
|
||||
protected function __construct(callable $callable)
|
||||
{
|
||||
$this->result = $callable();
|
||||
try {
|
||||
$this->result = $callable();
|
||||
} catch (GuzzleException $e) {
|
||||
// no response at all (connection refused, timeout)
|
||||
throw CollectionException::unreachable($e);
|
||||
}
|
||||
|
||||
if (!$this->result->success()) {
|
||||
throw new CollectionException(sprintf('%s for collection [%s]', rtrim($this->result->data->message, '.'), get_called_class()), $this->result->response->getStatusCode());
|
||||
throw CollectionException::fromResult($this->result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
namespace Anikeen\Id\Resources;
|
||||
|
||||
use Anikeen\Id\Exceptions\ApiException;
|
||||
use Anikeen\Id\Exceptions\ConfirmationRequiredException;
|
||||
use Anikeen\Id\Exceptions\ResourceException;
|
||||
use Anikeen\Id\Result;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use JsonSerializable;
|
||||
|
||||
#[\AllowDynamicProperties]
|
||||
@@ -13,11 +14,17 @@ abstract class BaseResource implements JsonSerializable
|
||||
public Result $result;
|
||||
|
||||
/**
|
||||
* @throws ResourceException
|
||||
* @throws ApiException the request failed (status, error code; a ResourceException)
|
||||
* @throws ConfirmationRequiredException the user has to confirm it on Anikeen ID
|
||||
*/
|
||||
public function __construct(callable $callable)
|
||||
{
|
||||
$this->result = $callable();
|
||||
try {
|
||||
$this->result = $callable();
|
||||
} catch (GuzzleException $e) {
|
||||
// no response at all (connection refused, timeout)
|
||||
throw ApiException::unreachable($e);
|
||||
}
|
||||
|
||||
if (!$this->result->success()) {
|
||||
if (($this->result->data->error ?? null) === 'confirmation_required') {
|
||||
@@ -28,7 +35,7 @@ abstract class BaseResource implements JsonSerializable
|
||||
);
|
||||
}
|
||||
|
||||
throw new ResourceException(sprintf('%s for resource [%s]', rtrim($this->result->data->message, '.'), get_called_class()), $this->result->response->getStatusCode());
|
||||
throw ApiException::fromResult($this->result);
|
||||
}
|
||||
|
||||
foreach ($this->result->data as $key => $value) {
|
||||
|
||||
Reference in new issue
Block a user