Skip to content

Commit 9bc00c6

Browse files
authored
Merge pull request #22 from Sammyjo20/feature/better-error-handling
Now returning original error and tidied up response
2 parents 76e960a + d944f4e commit 9bc00c6

File tree

5 files changed

+136
-77
lines changed

5 files changed

+136
-77
lines changed

src/Http/Middleware/MockMiddleware.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Sammyjo20\Saloon\Http\Middleware;
44

5-
use Psr\Http\Message\RequestInterface;
65
use Sammyjo20\Saloon\Http\MockResponse;
76
use GuzzleHttp\Promise\FulfilledPromise;
87

@@ -13,6 +12,9 @@ class MockMiddleware
1312
*/
1413
protected MockResponse $mockResponse;
1514

15+
/**
16+
* @param MockResponse $mockResponse
17+
*/
1618
public function __construct(MockResponse $mockResponse)
1719
{
1820
$this->mockResponse = $mockResponse;
@@ -26,7 +28,7 @@ public function __construct(MockResponse $mockResponse)
2628
*/
2729
public function __invoke(callable $handler)
2830
{
29-
return function (RequestInterface $request, array $options) use ($handler) {
31+
return function () {
3032
return new FulfilledPromise($this->mockResponse->toGuzzleResponse());
3133
};
3234
}

src/Http/SaloonResponse.php

Lines changed: 73 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
namespace Sammyjo20\Saloon\Http;
44

55
use Illuminate\Support\Arr;
6+
use GuzzleHttp\Psr7\Response;
7+
use GuzzleHttp\Cookie\CookieJar;
68
use Illuminate\Support\Collection;
79
use Illuminate\Support\Traits\Macroable;
10+
use GuzzleHttp\Exception\RequestException;
811
use Sammyjo20\Saloon\Exceptions\SaloonRequestException;
912

1013
class SaloonResponse
@@ -14,9 +17,9 @@ class SaloonResponse
1417
/**
1518
* The underlying PSR response.
1619
*
17-
* @var \Psr\Http\Message\ResponseInterface
20+
* @var Response
1821
*/
19-
protected $response;
22+
protected Response $response;
2023

2124
/**
2225
* The decoded JSON response.
@@ -30,7 +33,7 @@ class SaloonResponse
3033
*
3134
* @var array
3235
*/
33-
protected array $saloonRequestOptions;
36+
protected array $requestOptions;
3437

3538
/**
3639
* The original request
@@ -44,7 +47,14 @@ class SaloonResponse
4447
*
4548
* @var bool
4649
*/
47-
protected bool $shouldGuessStatusFromBody = false;
50+
protected bool $guessesStatusFromBody = false;
51+
52+
/**
53+
* The original Guzzle request exception
54+
*
55+
* @var RequestException|null
56+
*/
57+
protected ?RequestException $guzzleRequestException = null;
4858

4959
/**
5060
* Determines if the response has been cached
@@ -65,25 +75,25 @@ class SaloonResponse
6575
*
6676
* @param array $requestOptions
6777
* @param SaloonRequest $originalRequest
68-
* @param $response
69-
* @param bool $shouldGuessStatusFromBody
78+
* @param Response $response
79+
* @param RequestException|null $guzzleRequestException
7080
*/
71-
public function __construct(array $requestOptions, SaloonRequest $originalRequest, $response, bool $shouldGuessStatusFromBody = false)
81+
public function __construct(array $requestOptions, SaloonRequest $originalRequest, Response $response, RequestException $guzzleRequestException = null)
7282
{
73-
$this->saloonRequestOptions = $requestOptions;
83+
$this->requestOptions = $requestOptions;
7484
$this->originalRequest = $originalRequest;
7585
$this->response = $response;
76-
$this->shouldGuessStatusFromBody = $shouldGuessStatusFromBody;
86+
$this->guzzleRequestException = $guzzleRequestException;
7787
}
7888

7989
/**
8090
* Get the request options we attached to the request. Headers, Config etc.
8191
*
8292
* @return array
8393
*/
84-
public function getSaloonRequestOptions(): array
94+
public function getRequestOptions(): array
8595
{
86-
return $this->saloonRequestOptions;
96+
return $this->requestOptions;
8797
}
8898

8999
/**
@@ -103,14 +113,14 @@ public function getOriginalRequest(): SaloonRequest
103113
*/
104114
public function body()
105115
{
106-
return (string) $this->response->getBody();
116+
return (string)$this->response->getBody();
107117
}
108118

109119
/**
110120
* Get the JSON decoded body of the response as an array or scalar value.
111121
*
112-
* @param string|null $key
113-
* @param mixed $default
122+
* @param string|null $key
123+
* @param mixed $default
114124
* @return mixed
115125
*/
116126
public function json($key = null, $default = null)
@@ -139,21 +149,21 @@ public function object()
139149
/**
140150
* Get the JSON decoded body of the response as a collection.
141151
*
142-
* @param string|null $key
143-
* @return \Illuminate\Support\Collection
152+
* @param $key
153+
* @return Collection
144154
*/
145-
public function collect($key = null)
155+
public function collect($key = null): Collection
146156
{
147157
return Collection::make($this->json($key));
148158
}
149159

150160
/**
151161
* Get a header from the response.
152162
*
153-
* @param string $header
163+
* @param string $header
154164
* @return string
155165
*/
156-
public function header(string $header)
166+
public function header(string $header): string
157167
{
158168
return $this->response->getHeaderLine($header);
159169
}
@@ -163,7 +173,7 @@ public function header(string $header)
163173
*
164174
* @return array
165175
*/
166-
public function headers()
176+
public function headers(): array
167177
{
168178
return $this->response->getHeaders();
169179
}
@@ -173,19 +183,19 @@ public function headers()
173183
*
174184
* @return int
175185
*/
176-
public function getStatusFromResponse(): int
186+
private function getStatusFromResponse(): int
177187
{
178-
return (int) $this->response->getStatusCode();
188+
return (int)$this->response->getStatusCode();
179189
}
180190

181191
/**
182192
* Get the status code of the response.
183193
*
184194
* @return int
185195
*/
186-
public function status()
196+
public function status(): int
187197
{
188-
if ($this->shouldGuessStatusFromBody === true) {
198+
if ($this->guessesStatusFromBody === true) {
189199
return $this->guessStatusFromBody();
190200
}
191201

@@ -200,33 +210,15 @@ public function status()
200210
*
201211
* @return int
202212
*/
203-
public function guessStatusFromBody(): int
213+
private function guessStatusFromBody(): int
204214
{
205-
$body = $this->json('status', null);
206-
207-
if (isset($body) === false) {
208-
return $this->getStatusFromResponse();
209-
}
210-
211-
if (! preg_match('/^[1-5][0-9][0-9]$/', $body)) {
212-
return $this->getStatusFromResponse();
213-
}
215+
$status = $this->json('status');
214216

215-
if (is_numeric($body) === false) {
216-
return $this->getStatusFromResponse();
217+
if (preg_match('/^[1-5][0-9][0-9]$/', $status)) {
218+
return (int)$status;
217219
}
218220

219-
return (int)$body;
220-
}
221-
222-
/**
223-
* Get the effective URI of the response.
224-
*
225-
* @return \Psr\Http\Message\UriInterface|null
226-
*/
227-
public function effectiveUri()
228-
{
229-
return optional($this->transferStats)->getEffectiveUri();
221+
return $this->getStatusFromResponse();
230222
}
231223

232224
/**
@@ -292,10 +284,10 @@ public function serverError()
292284
/**
293285
* Execute the given callback if there was a server or client error.
294286
*
295-
* @param callable $callback
287+
* @param callable $callback
296288
* @return $this
297289
*/
298-
public function onError(callable $callback)
290+
public function onError(callable $callback): self
299291
{
300292
if ($this->failed()) {
301293
$callback($this);
@@ -309,27 +301,17 @@ public function onError(callable $callback)
309301
*
310302
* @return \GuzzleHttp\Cookie\CookieJar
311303
*/
312-
public function cookies()
304+
public function cookies(): CookieJar
313305
{
314306
return $this->cookies;
315307
}
316308

317-
/**
318-
* Get the handler stats of the response.
319-
*
320-
* @return array
321-
*/
322-
public function handlerStats()
323-
{
324-
return optional($this->transferStats)->getHandlerStats() ?? [];
325-
}
326-
327309
/**
328310
* Close the stream and any underlying resources.
329311
*
330312
* @return $this
331313
*/
332-
public function close()
314+
public function close(): self
333315
{
334316
$this->response->getBody()->close();
335317

@@ -339,19 +321,19 @@ public function close()
339321
/**
340322
* Get the underlying PSR response for the response.
341323
*
342-
* @return \Psr\Http\Message\ResponseInterface
324+
* @return Response
343325
*/
344-
public function toPsrResponse()
326+
public function toPsrResponse(): Response
345327
{
346328
return $this->response;
347329
}
348330

349331
/**
350332
* Get the underlying PSR response for the response.
351333
*
352-
* @return \Psr\Http\Message\ResponseInterface
334+
* @return Response
353335
*/
354-
public function toGuzzleResponse()
336+
public function toGuzzleResponse(): Response
355337
{
356338
return $this->toPsrResponse();
357339
}
@@ -364,15 +346,17 @@ public function toGuzzleResponse()
364346
public function toException()
365347
{
366348
if ($this->failed()) {
367-
return new SaloonRequestException($this, $this->response?->getBody()?->getContents());
349+
$body = $this->response?->getBody()?->getContents();
350+
351+
return new SaloonRequestException($this, $body, 0, $this->guzzleRequestException);
368352
}
369353
}
370354

371355
/**
372356
* Throw an exception if a server or client error occurred.
373357
*
374358
* @return $this
375-
* @throws SaloonException
359+
* @throws SaloonRequestException
376360
*/
377361
public function throw()
378362
{
@@ -438,4 +422,26 @@ public function isMocked(): bool
438422
{
439423
return $this->isMocked;
440424
}
425+
426+
/**
427+
* Get the original request exception
428+
*
429+
* @return RequestException|null
430+
*/
431+
public function getGuzzleException(): ?RequestException
432+
{
433+
return $this->guzzleRequestException;
434+
}
435+
436+
/**
437+
* Should the response guess the status from the body?
438+
*
439+
* @return $this
440+
*/
441+
public function guessesStatusFromBody(): self
442+
{
443+
$this->guessesStatusFromBody = true;
444+
445+
return $this;
446+
}
441447
}

src/Managers/RequestManager.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Sammyjo20\Saloon\Clients\MockClient;
99
use Sammyjo20\Saloon\Http\SaloonRequest;
1010
use Sammyjo20\Saloon\Http\SaloonResponse;
11+
use GuzzleHttp\Exception\RequestException;
1112
use Sammyjo20\Saloon\Http\SaloonConnector;
1213
use Sammyjo20\Saloon\Traits\ManagesGuzzle;
1314
use Sammyjo20\Saloon\Traits\CollectsConfig;
@@ -175,7 +176,7 @@ public function send()
175176
try {
176177
$guzzleResponse = $client->send($this->createGuzzleRequest(), $requestOptions);
177178
} catch (BadResponseException $exception) {
178-
return $this->createResponse($requestOptions, $exception->getResponse());
179+
return $this->createResponse($requestOptions, $exception->getResponse(), $exception);
179180
}
180181

181182
return $this->createResponse($requestOptions, $guzzleResponse);
@@ -186,23 +187,26 @@ public function send()
186187
*
187188
* @param array $requestOptions
188189
* @param Response $response
190+
* @param RequestException|null $exception
189191
* @return SaloonResponse
190-
* @throws \ReflectionException
191192
* @throws SaloonInvalidResponseClassException
192-
*
193+
* @throws \ReflectionException
194+
* @throws \Sammyjo20\Saloon\Exceptions\SaloonInvalidConnectorException
193195
*/
194-
private function createResponse(array $requestOptions, Response $response): SaloonResponse
196+
private function createResponse(array $requestOptions, Response $response, RequestException $exception = null): SaloonResponse
195197
{
196198
$request = $this->request;
197-
198-
$shouldGuessStatusFromBody = isset($this->connector->shouldGuessStatusFromBody) || isset($this->request->shouldGuessStatusFromBody);
199-
200199
$responseClass = $request->getResponseClass();
201200

202-
$response = new $responseClass($requestOptions, $request, $response, $shouldGuessStatusFromBody);
201+
/** @var SaloonResponse $response */
202+
$response = new $responseClass($requestOptions, $request, $response, $exception);
203203

204204
$response->setMocked($this->isMocking());
205205

206+
if (property_exists($this->connector, 'shouldGuessStatusFromBody') || property_exists($this->request, 'shouldGuessStatusFromBody')) {
207+
$response->guessesStatusFromBody();
208+
}
209+
206210
// Run Response Interceptors
207211

208212
foreach ($this->getResponseInterceptors() as $responseInterceptor) {

0 commit comments

Comments
 (0)