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); } /** * The JSON body of Anikeen ID's error response, null without one. Some errors carry details, * e.g. `net_amount` of "elapsed_amount_exceeded". */ public function body(): ?object { $previous = $this->getPrevious(); $response = $previous !== null && method_exists($previous, 'getResponse') ? $previous->getResponse() : null; if (!$response instanceof ResponseInterface) { return null; } $body = json_decode((string) $response->getBody()); return is_object($body) ? $body : null; } 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; } }