Files
id/src/Id/Exceptions/ApiException.php
T
Maurice PreußandClaude Opus 5.5 8de737641e App subscriptions: manage a user's subscriptions with the app's own token
- $user->appSubscriptions(): create (idempotency_key), find, all, checkout, revoke, pause,
  resume, update against /v1/client/subscriptions with a client credentials token, so apps don't
  depend on the user's login
- user id from the billable's anikeen_id (AnikeenId::useUserIdField())
- ApiException with status, stable error code, isNotFound/isConflict/isTemporary; network
  errors no longer escape as raw Guzzle exceptions
- rejected app tokens are renewed once; asApp() never changes the shared client's token
- tests (testbench + Guzzle mock) and CI

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 17:02:16 +01:00

40 lines
1000 B
PHP

<?php
namespace Anikeen\Id\Exceptions;
use Throwable;
/**
* A request to the ID service failed. `status` is the HTTP status (0 when the service could not
* be reached), `error` the service's stable error code when it sent one (e.g. "already_cancelled").
*/
class ApiException extends ResourceException
{
public function __construct(
string $message,
public readonly int $status = 0,
public readonly ?string $error = null,
?Throwable $previous = null,
) {
parent::__construct($message, $status, $previous);
}
public function isNotFound(): bool
{
return $this->status === 404;
}
public function isConflict(): bool
{
return $this->status === 409;
}
/**
* The ID service could not be reached (network error, timeout) or failed (5xx): retry later.
*/
public function isTemporary(): bool
{
return $this->status === 0 || $this->status >= 500 || $this->status === 429;
}
}