From ddf95c7adc5f3d229b29519815630a3198ff5a13 Mon Sep 17 00:00:00 2001 From: Jerome TAMARELLE Date: Fri, 18 Jul 2014 15:26:18 +0200 Subject: [PATCH 1/4] [HttpFoundation] Silent only JSON errors --- .../Component/HttpFoundation/JsonResponse.php | 15 ++++++++++- .../HttpFoundation/Tests/JsonResponseTest.php | 27 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index 6460021463..27398974d8 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -95,7 +95,20 @@ class JsonResponse extends Response */ public function setData($data = array()) { - $this->data = @json_encode($data, $this->encodingOptions); + $errorHandler = null; + $errorHandler = set_error_handler(function () use (&$errorHandler) { + if (JSON_ERROR_NONE !== json_last_error()) { + return; + } + + if ($errorHandler) { + call_user_func_array($errorHandler, func_get_args()); + } + }); + + $this->data = json_encode($data, $this->encodingOptions); + + restore_error_handler(); if (JSON_ERROR_NONE !== json_last_error()) { throw new \InvalidArgumentException($this->transformJsonError()); diff --git a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php index e9325f4b12..e458372828 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -201,4 +201,31 @@ class JsonResponseTest extends \PHPUnit_Framework_TestCase { JsonResponse::create("\xB1\x31"); } + + /** + * @expectedException PHPUnit_Framework_Error_Warning + * @expectedExceptionMessage This error is expected + */ + public function testSetContentJsonSerializeError() + { + if (!interface_exists('JsonSerializable')) { + $this->markTestSkipped('Interface JsonSerializable is available in PHP 5.4+'); + } + + $serializable = new JsonSerializableObject(); + + JsonResponse::create($serializable); + } +} + +if (interface_exists('JsonSerializable')) { + class JsonSerializableObject implements JsonSerializable + { + public function jsonSerialize() + { + trigger_error('This error is expected', E_USER_WARNING); + + return array(); + } + } } From d952f9049ebe4ed753c4bc4cbaab923e48da4be5 Mon Sep 17 00:00:00 2001 From: Jerome TAMARELLE Date: Fri, 18 Jul 2014 16:10:40 +0200 Subject: [PATCH 2/4] Catch exceptions to restore the error handler --- src/Symfony/Component/HttpFoundation/JsonResponse.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index 27398974d8..4080ee8fb6 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -106,9 +106,15 @@ class JsonResponse extends Response } }); - $this->data = json_encode($data, $this->encodingOptions); + try { + $this->data = json_encode($data, $this->encodingOptions); - restore_error_handler(); + restore_error_handler(); + } catch (\Exception $exception) { + restore_error_handler(); + + throw $exception; + } if (JSON_ERROR_NONE !== json_last_error()) { throw new \InvalidArgumentException($this->transformJsonError()); From ef91f710e3d76c563361c6a69082593c4a89b3b0 Mon Sep 17 00:00:00 2001 From: Jerome TAMARELLE Date: Fri, 18 Jul 2014 16:26:19 +0200 Subject: [PATCH 3/4] Fix JsonSerializable namespace --- src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php index e458372828..f4f3c6c416 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -219,7 +219,7 @@ class JsonResponseTest extends \PHPUnit_Framework_TestCase } if (interface_exists('JsonSerializable')) { - class JsonSerializableObject implements JsonSerializable + class JsonSerializableObject implements \JsonSerializable { public function jsonSerialize() { From 6d6a3af4ff9711de24acabc32c4c38f5b0bb8938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 15 Sep 2014 23:11:34 +0200 Subject: [PATCH 4/4] Clear json_last_error --- src/Symfony/Component/HttpFoundation/JsonResponse.php | 3 +++ .../Component/HttpFoundation/Tests/JsonResponseTest.php | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index 4080ee8fb6..accd57cf3a 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -107,6 +107,9 @@ class JsonResponse extends Response }); try { + // Clear json_last_error() + json_encode(null); + $this->data = json_encode($data, $this->encodingOptions); restore_error_handler(); diff --git a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php index f4f3c6c416..48b86038a7 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -203,8 +203,9 @@ class JsonResponseTest extends \PHPUnit_Framework_TestCase } /** - * @expectedException PHPUnit_Framework_Error_Warning - * @expectedExceptionMessage This error is expected + * @expectedException Exception + * @expectedExceptionMessage Failed calling Symfony\Component\HttpFoundation\Tests\JsonSerializableObject::jsonSerialize() + * @link http://php.net/manual/en/jsonserializable.jsonserialize.php#114688 */ public function testSetContentJsonSerializeError() {