Skip to content

Commit

Permalink
Handle undecodable responses gracefully (#25)
Browse files Browse the repository at this point in the history
* Handle undecodable responses gracefully

Introduced a try-catch block in the data() method to catch
`NotDecodableException` when attempting to decode response data. In such
cases, decoding will now default to an empty array instead of throwing
an unhandled exception. Moreover, clarified method return types in doc
comments for `onError`, `throw`, and `throwIf` to reflect the generic
`Response<T>` type.

* Test

* Change version label
  • Loading branch information
jenky committed Jan 5, 2024
1 parent fe40221 commit c5e9ed0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/retype.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ url: phanxipang.github.io/fansipan

branding:
title: Fansipan
label: 1.0-RC1
label: 1.0-RC

edit:
repo: https://github.com/phanxipang/fansipan
Expand Down
16 changes: 13 additions & 3 deletions src/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Fansipan\Contracts\DecoderInterface;
use Fansipan\Contracts\MapperInterface;
use Fansipan\Exception\HttpException;
use Fansipan\Exception\NotDecodableException;
use LogicException;
use Psr\Http\Message\ResponseInterface;

Expand Down Expand Up @@ -57,7 +58,11 @@ public function body(): string
public function data(): array
{
if (! $this->decoded) {
$this->decoded = Util::iteratorToArray($this->decode());
try {
$this->decoded = Util::iteratorToArray($this->decode());
} catch (NotDecodableException $e) {
$this->decoded = [];
}
}

return $this->decoded;
Expand All @@ -80,12 +85,12 @@ public function object(): ?object
/**
* Get the decoded body the response.
*
* @throws \Fansipan\Exception\NotDecodableException
* @throws NotDecodableException
*/
public function decode(): iterable
{
if (! $this->decoder instanceof DecoderInterface) {
return [];
throw NotDecodableException::create();
}

return $this->decoder->decode($this->response);
Expand Down Expand Up @@ -191,6 +196,8 @@ public function serverError(): bool

/**
* Execute the given callback if there was a server or client error.
*
* @return Response<T>
*/
public function onError(callable $callback): self
{
Expand Down Expand Up @@ -228,6 +235,8 @@ public function toException(): ?HttpException
/**
* Throw an exception if a server or client error occurred.
*
* @return Response<T>
*
* @throws \Fansipan\Exception\HttpException
*/
public function throw(): self
Expand Down Expand Up @@ -255,6 +264,7 @@ public function throw(): self
* Throw an exception if a server or client error occurred and the given condition evaluates to true.
*
* @param \Closure|bool $condition
* @return Response<T>
*
* @throws \Fansipan\Exception\HttpException
*/
Expand Down
12 changes: 12 additions & 0 deletions tests/ResponseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Fansipan\Tests;

use Fansipan\Exception\NotDecodableException;
use Fansipan\Mock\MockClient;
use Fansipan\Mock\MockResponse;
use Fansipan\Response;
Expand Down Expand Up @@ -76,4 +77,15 @@ public function test_response_can_be_json_serialize(): void
$this->assertJson($json = \json_encode($response));
$this->assertJsonStringEqualsJsonFile($file, $json);
}

public function test_response_without_decoder(): void
{
$response = new Response(MockResponse::create(''));

$this->expectException(NotDecodableException::class);

$response->decode();

$this->assertIsArray($response->data());
}
}

0 comments on commit c5e9ed0

Please sign in to comment.