Skip to content

Commit 04e767f

Browse files
author
Mohamed Khaled
committed
Implement PSR-18 exception interfaces for HTTP client compliance
1 parent c0d3b74 commit 04e767f

File tree

4 files changed

+88
-9
lines changed

4 files changed

+88
-9
lines changed

src/Providers/Http/Exception/NetworkException.php

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace WordPress\AiClient\Providers\Http\Exception;
66

7+
use Psr\Http\Client\NetworkExceptionInterface;
8+
use Psr\Http\Message\RequestInterface;
79
use WordPress\AiClient\Common\Exception\RuntimeException;
810

911
/**
@@ -14,25 +16,53 @@
1416
*
1517
* @since n.e.x.t
1618
*/
17-
class NetworkException extends RuntimeException
19+
class NetworkException extends RuntimeException implements NetworkExceptionInterface
1820
{
21+
/**
22+
* The request that failed.
23+
*
24+
* @var RequestInterface|null
25+
*/
26+
private ?RequestInterface $request = null;
27+
1928
/**
2029
* Creates a NetworkException from a PSR-18 network exception.
2130
*
2231
* @since n.e.x.t
2332
*
24-
* @param string $uri The URI that was being requested.
33+
* @param RequestInterface $request The request that failed.
2534
* @param \Throwable $networkException The PSR-18 network exception.
2635
* @return self
2736
*/
28-
public static function fromPsr18NetworkException(string $uri, \Throwable $networkException): self
37+
public static function fromPsr18NetworkException(RequestInterface $request, \Throwable $networkException): self
2938
{
3039
$message = sprintf(
3140
'Network error occurred while sending request to %s: %s',
32-
$uri,
41+
(string) $request->getUri(),
3342
$networkException->getMessage()
3443
);
3544

36-
return new self($message, 0, $networkException);
45+
$exception = new self($message, 0, $networkException);
46+
$exception->request = $request;
47+
return $exception;
48+
}
49+
50+
/**
51+
* Returns the request that failed.
52+
*
53+
* @since n.e.x.t
54+
*
55+
* @return RequestInterface
56+
* @throws \RuntimeException If no request is available (when directly instantiated)
57+
*/
58+
public function getRequest(): RequestInterface
59+
{
60+
if ($this->request === null) {
61+
throw new \RuntimeException(
62+
'Request object not available. This exception was directly instantiated. Use fromPsr18NetworkException() factory method for PSR-18 compliance.'
63+
);
64+
}
65+
66+
return $this->request;
3767
}
3868
}

src/Providers/Http/Exception/RequestException.php

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace WordPress\AiClient\Providers\Http\Exception;
66

7+
use Psr\Http\Client\RequestExceptionInterface;
8+
use Psr\Http\Message\RequestInterface;
79
use WordPress\AiClient\Common\Exception\InvalidArgumentException;
810

911
/**
@@ -15,8 +17,33 @@
1517
*
1618
* @since n.e.x.t
1719
*/
18-
class RequestException extends InvalidArgumentException
20+
class RequestException extends InvalidArgumentException implements RequestExceptionInterface
1921
{
22+
/**
23+
* The request that failed.
24+
*
25+
* @var RequestInterface|null
26+
*/
27+
private ?RequestInterface $request = null;
28+
29+
/**
30+
* Creates a RequestException from a bad request.
31+
*
32+
* @since n.e.x.t
33+
*
34+
* @param RequestInterface $request The request that failed.
35+
* @param string $errorDetail Details about what made the request bad.
36+
* @return self
37+
*/
38+
public static function fromBadRequest(RequestInterface $request, string $errorDetail = 'Invalid request parameters'): self
39+
{
40+
$message = sprintf('Bad request to %s (400): %s', (string) $request->getUri(), $errorDetail);
41+
42+
$exception = new self($message);
43+
$exception->request = $request;
44+
return $exception;
45+
}
46+
2047
/**
2148
* Creates a RequestException from a bad request to a specific URI.
2249
*
@@ -25,9 +52,30 @@ class RequestException extends InvalidArgumentException
2552
* @param string $uri The URI that was requested.
2653
* @param string $errorDetail Details about what made the request bad.
2754
* @return self
55+
*
56+
* @deprecated Use fromBadRequest() with RequestInterface for PSR-18 compliance
2857
*/
2958
public static function fromBadRequestToUri(string $uri, string $errorDetail = 'Invalid request parameters'): self
3059
{
3160
return new self(sprintf('Bad request to %s (400): %s', $uri, $errorDetail));
3261
}
62+
63+
/**
64+
* Returns the request that failed.
65+
*
66+
* @since n.e.x.t
67+
*
68+
* @return RequestInterface
69+
* @throws \RuntimeException If no request is available (when using deprecated fromBadRequestToUri)
70+
*/
71+
public function getRequest(): RequestInterface
72+
{
73+
if ($this->request === null) {
74+
throw new \RuntimeException(
75+
'Request object not available. This exception was created using the deprecated fromBadRequestToUri() method. Use fromBadRequest() instead for PSR-18 compliance.'
76+
);
77+
}
78+
79+
return $this->request;
80+
}
3381
}

src/Providers/Http/Exception/ResponseException.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace WordPress\AiClient\Providers\Http\Exception;
66

7+
use Psr\Http\Client\ClientExceptionInterface;
78
use WordPress\AiClient\Common\Exception\RuntimeException;
89
use WordPress\AiClient\Providers\Http\DTO\Response;
910

@@ -16,7 +17,7 @@
1617
*
1718
* @since 0.1.0
1819
*/
19-
class ResponseException extends RuntimeException
20+
class ResponseException extends RuntimeException implements ClientExceptionInterface
2021
{
2122
/**
2223
* Creates a ResponseException for missing expected data.

src/Providers/Http/HttpTransporter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public function send(Request $request): Response
7575
try {
7676
$psr7Response = $this->client->sendRequest($psr7Request);
7777
} catch (\Psr\Http\Client\NetworkExceptionInterface $e) {
78-
throw NetworkException::fromPsr18NetworkException($request->getUri(), $e);
78+
throw NetworkException::fromPsr18NetworkException($psr7Request, $e);
7979
} catch (\Psr\Http\Client\ClientExceptionInterface $e) {
8080
// Handle other PSR-18 client exceptions that are not network-related
8181
throw new RuntimeException(
@@ -93,7 +93,7 @@ public function send(Request $request): Response
9393
if ($psr7Response->getStatusCode() === 400) {
9494
$body = (string) $psr7Response->getBody();
9595
$errorDetail = $body ? substr($body, 0, 200) : 'Invalid request parameters';
96-
throw RequestException::fromBadRequestToUri($request->getUri(), $errorDetail);
96+
throw RequestException::fromBadRequest($psr7Request, $errorDetail);
9797
}
9898

9999
return $this->convertFromPsr7Response($psr7Response);

0 commit comments

Comments
 (0)