From bd0f7981c5d5ab8aa751d61b1624c968de4a1c4d 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 6460021463fa5..27398974d86d5 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -95,7 +95,20 @@ public function setCallback($callback = null) */ 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 e9325f4b12c75..e45837282808c 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -201,4 +201,31 @@ public function testSetContent() { 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 6e8c7fc64bcd1d56a03c5adc8f8ad6077dda33aa 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 27398974d86d5..4080ee8fb6edb 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -106,9 +106,15 @@ public function setData($data = array()) } }); - $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 a4a8535751089420610f5ab0587cc55e793a0662 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 e45837282808c..f4f3c6c416fd7 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -219,7 +219,7 @@ public function testSetContentJsonSerializeError() } if (interface_exists('JsonSerializable')) { - class JsonSerializableObject implements JsonSerializable + class JsonSerializableObject implements \JsonSerializable { public function jsonSerialize() { From c2a1a5b0918eb9d904877b68f69054bfe70a0c1a 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 4080ee8fb6edb..accd57cf3adc8 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -107,6 +107,9 @@ public function setData($data = array()) }); 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 f4f3c6c416fd7..48b86038a7e15 100644 --- a/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php +++ b/src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php @@ -203,8 +203,9 @@ public function testSetContent() } /** - * @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() {