bug #38122 [HttpClient] Fix Array to string conversion notice when parsing JSON error body with non-scalar detail property (emarref)
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[HttpClient] Fix Array to string conversion notice when parsing JSON error body with non-scalar detail property
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | Fix #38118
| License | MIT
| Doc PR | no
An earlier commit added the ability to detect common API formats and extract a useful error message from the error response payload. To achieve this, if a `title` and `detail` property are found in the error response, the response is considered to be in a known format (RFC 7807) and these values are concatenated to form a helpful error message.
However, when either `title` or `detail` property are present, but the document is not intended to follow the RFC semantics, if the properties are not scalar (e.g. if the detail property is an array of field validation violations) then the concatenation of the strings causes a notice to be raised.
This pull request checks that the `title` and `detail` properties are scalar before attempting to concatenate them. If they are not, no enhanced error message is provided.
Commits
-------
76fa884319
[HttpClient] Fix Array to string conversion notice when parsing JSON error body with non-scalar detail property
This commit is contained in:
commit
9bb80841ed
@ -60,7 +60,8 @@ trait HttpExceptionTrait
|
||||
// see http://www.hydra-cg.com/spec/latest/core/#description-of-http-status-codes-and-errors
|
||||
$separator = isset($body['hydra:title'], $body['hydra:description']) ? "\n\n" : '';
|
||||
$message = ($body['hydra:title'] ?? '').$separator.($body['hydra:description'] ?? '');
|
||||
} elseif (isset($body['title']) || isset($body['detail'])) {
|
||||
} elseif ((isset($body['title']) || isset($body['detail']))
|
||||
&& (is_scalar($body['title'] ?? '') && is_scalar($body['detail'] ?? ''))) {
|
||||
// see RFC 7807 and https://jsonapi.org/format/#error-objects
|
||||
$separator = isset($body['title'], $body['detail']) ? "\n\n" : '';
|
||||
$message = ($body['title'] ?? '').$separator.($body['detail'] ?? '');
|
||||
|
@ -22,15 +22,24 @@ class HttpExceptionTraitTest extends TestCase
|
||||
{
|
||||
public function provideParseError(): iterable
|
||||
{
|
||||
yield ['application/ld+json', '{"hydra:title": "An error occurred", "hydra:description": "Some details"}'];
|
||||
yield ['application/problem+json', '{"title": "An error occurred", "detail": "Some details"}'];
|
||||
yield ['application/vnd.api+json', '{"title": "An error occurred", "detail": "Some details"}'];
|
||||
$errorWithoutMessage = 'HTTP/1.1 400 Bad Request returned for "http://example.com".';
|
||||
|
||||
$errorWithMessage = <<<ERROR
|
||||
An error occurred
|
||||
|
||||
Some details
|
||||
ERROR;
|
||||
|
||||
yield ['application/ld+json', '{"hydra:title": "An error occurred", "hydra:description": "Some details"}', $errorWithMessage];
|
||||
yield ['application/problem+json', '{"title": "An error occurred", "detail": "Some details"}', $errorWithMessage];
|
||||
yield ['application/vnd.api+json', '{"title": "An error occurred", "detail": "Some details"}', $errorWithMessage];
|
||||
yield ['application/json', '{"title": "An error occurred", "detail": {"field_name": ["Some details"]}}', $errorWithoutMessage];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideParseError
|
||||
*/
|
||||
public function testParseError(string $mimeType, string $json): void
|
||||
public function testParseError(string $mimeType, string $json, string $expectedMessage): void
|
||||
{
|
||||
$response = $this->createMock(ResponseInterface::class);
|
||||
$response
|
||||
@ -47,12 +56,7 @@ class HttpExceptionTraitTest extends TestCase
|
||||
|
||||
$e = new TestException($response);
|
||||
$this->assertSame(400, $e->getCode());
|
||||
$this->assertSame(<<<ERROR
|
||||
An error occurred
|
||||
|
||||
Some details
|
||||
ERROR
|
||||
, $e->getMessage());
|
||||
$this->assertSame($expectedMessage, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user