8000 [HttpClient][DX] Add URL context to JsonException messages · symfony/symfony@0653917 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0653917

Browse files
GromNaNnicolas-grekas
authored andcommitted
[HttpClient][DX] Add URL context to JsonException messages
1 parent 88b89c9 commit 0653917

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed

src/Symfony/Component/HttpClient/Response/ResponseTrait.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,21 +147,21 @@ public function toArray(bool $throw = true): array
147147
$contentType = $this->headers['content-type'][0] ?? 'application/json';
148148

149149
if (!preg_match('/\bjson\b/i', $contentType)) {
150-
throw new JsonException(sprintf('Response content-type is "%s" while a JSON-compatible one was expected.', $contentType));
150+
throw new JsonException(sprintf('Response content-type is "%s" while a JSON-compatible one was expected for "%s".', $contentType, $this->getInfo('url')));
151151
}
152152

153153
try {
154154
$content = json_decode($content, true, 512, JSON_BIGINT_AS_STRING | (\PHP_VERSION_ID >= 70300 ? JSON_THROW_ON_ERROR : 0));
155155
} catch (\JsonException $e) {
156-
throw new JsonException($e->getMessage(), $e->getCode());
156+
throw new JsonException(sprintf('%s for "%s".', $e->getMessage(), $this->getInfo('url')), $e->getCode());
157157
}
158158

159159
if (\PHP_VERSION_ID < 70300 && JSON_ERROR_NONE !== json_last_error()) {
160-
throw new JsonException(json_last_error_msg(), json_last_error());
160+
throw new JsonException(sprintf('%s for "%s".', json_last_error_msg(), $this->getInfo('url')), json_last_error());
161161
}
162162

163163
if (!\is_array($content)) {
164-
throw new JsonException(sprintf('JSON content was expected to decode to an array, %s returned.', \gettype($content)));
164+
throw new JsonException(sprintf('JSON content was expected to decode to an array, %s returned for "%s".', \gettype($content), $this->getInfo('url')));
165165
}
166166

167167
if (null !== $this->content) {
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
namespace Symfony\Component\HttpClient\Tests\Response;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Symfony\Component\HttpClient\Exception\JsonException;
7+
use Symfony\Component\HttpClient\Response\MockResponse;
8+
9+
/**
10+
* Test methods from Symfony\Component\HttpClient\Response\ResponseTrait.
11+
*/
12+
class MockResponseTest extends TestCase
13+
{
14+
public function testToArray()
15+
{
16+
$data = ['color' => 'orange', 'size' => 42];
17+
$response = new MockResponse(json_encode($data));
18+
$response = MockResponse::fromRequest('GET', 'https://example.com/file.json', [], $response);
19+
20+
$this->assertSame($data, $response->toArray());
21+
}
22+
23+
/**
24+
* @dataProvider toArrayErrors
25+
*/
26+
public function testToArrayError($content, $responseHeaders, $message)
27+
{
28+
$this->expectException(JsonException::class);
29+
$this->expectExceptionMessage($message);
30+
31+
$response = new MockResponse($content, ['response_headers' => $responseHeaders]);
32+
$response = MockResponse::fromRequest('GET', 'https://example.com/file.json', [], $response);
33+
$response->toArray();
34+
}
35+
36+
public function toArrayErrors()
37+
{
38+
yield [
39+
'content' => '{}',
40+
'responseHeaders' => ['content-type' => 'plain/text'],
41+
'message' => 'Response content-type is "plain/text" while a JSON-compatible one was expected for "https://example.com/file.json".',
42+
];
43+
44+
yield [
45+
'content' => 'not json',
46+
'responseHeaders' => [],
47+
'message' => 'Syntax error for "https://example.com/file.json".',
48+
];
49+
50+
yield [
51+
'content' => '[1,2}',
52+
'responseHeaders' => [],
53+
'message' => 'State mismatch (invalid or malformed JSON) for "https://example.com/file.json".',
54+
];
55+
56+
yield [
57+
'content' => '"not an array"',
58+
'responseHeaders' => [],
59+
'message' => 'JSON content was expected to decode to an array, string returned for "https://example.com/file.json".',
60+
];
61+
62+
yield [
63+
'content' => '8',
64+
'responseHeaders' => [],
65+
'message' => 'JSON content was expected to decode to an array, integer returned for "https://example.com/file.json".',
66+
];
67+
}
68+
}

0 commit comments

Comments
 (0)
1618
0