mirror of
https://github.com/Seldaek/monolog.git
synced 2025-08-06 13:16:39 +02:00
Resolve json encoding errors issue globally, refs #137
This commit is contained in:
@@ -81,10 +81,11 @@ class LineFormatter extends NormalizerFormatter
|
|||||||
return (string) $data;
|
return (string) $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$data = $this->normalize($data);
|
||||||
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
||||||
return json_encode($this->normalize($data), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
return $this->toJson($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return str_replace('\\/', '/', json_encode($this->normalize($data)));
|
return str_replace('\\/', '/', json_encode($data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -71,7 +71,7 @@ class NormalizerFormatter implements FormatterInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_object($data)) {
|
if (is_object($data)) {
|
||||||
return sprintf("[object] (%s: %s)", get_class($data), $this->toJson($data));
|
return sprintf("[object] (%s: %s)", get_class($data), $this->toJson($data, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_resource($data)) {
|
if (is_resource($data)) {
|
||||||
@@ -81,8 +81,17 @@ class NormalizerFormatter implements FormatterInterface
|
|||||||
return '[unknown('.gettype($data).')]';
|
return '[unknown('.gettype($data).')]';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function toJson($data)
|
protected function toJson($data, $ignoreErrors = false)
|
||||||
{
|
{
|
||||||
|
// suppress json_encode errors since it's twitchy with some inputs
|
||||||
|
if ($ignoreErrors) {
|
||||||
|
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
||||||
|
return @json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return @json_encode($data);
|
||||||
|
}
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
|
||||||
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
}
|
}
|
||||||
|
@@ -67,13 +67,8 @@ class WildfireFormatter extends NormalizerFormatter
|
|||||||
$message = reset($message);
|
$message = reset($message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle json_encode recursion error
|
|
||||||
if ($handleError) {
|
|
||||||
set_error_handler(function () { });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create JSON object describing the appearance of the message in the console
|
// Create JSON object describing the appearance of the message in the console
|
||||||
$json = json_encode(array(
|
$json = $this->toJson(array(
|
||||||
array(
|
array(
|
||||||
'Type' => $this->logLevels[$record['level']],
|
'Type' => $this->logLevels[$record['level']],
|
||||||
'File' => $file,
|
'File' => $file,
|
||||||
@@ -81,11 +76,7 @@ class WildfireFormatter extends NormalizerFormatter
|
|||||||
'Label' => $record['channel'],
|
'Label' => $record['channel'],
|
||||||
),
|
),
|
||||||
$message,
|
$message,
|
||||||
));
|
), $handleError);
|
||||||
|
|
||||||
if ($handleError) {
|
|
||||||
restore_error_handler();
|
|
||||||
}
|
|
||||||
|
|
||||||
// The message itself is a serialization of the above JSON object + it's length
|
// The message itself is a serialization of the above JSON object + it's length
|
||||||
return sprintf(
|
return sprintf(
|
||||||
|
@@ -89,6 +89,61 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase
|
|||||||
),
|
),
|
||||||
), $formatted);
|
), $formatted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test issue #137
|
||||||
|
*/
|
||||||
|
public function testIgnoresRecursiveObjectReferences()
|
||||||
|
{
|
||||||
|
// set up the recursion
|
||||||
|
$foo = new \stdClass();
|
||||||
|
$bar = new \stdClass();
|
||||||
|
|
||||||
|
$foo->bar = $bar;
|
||||||
|
$bar->foo = $foo;
|
||||||
|
|
||||||
|
// set an error handler to assert that the error is not raised anymore
|
||||||
|
$that = $this;
|
||||||
|
set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
|
||||||
|
if (error_reporting() & $level) {
|
||||||
|
restore_error_handler();
|
||||||
|
$that->fail("$message should not be raised");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$formatter = new NormalizerFormatter();
|
||||||
|
$reflMethod = new \ReflectionMethod($formatter, 'toJson');
|
||||||
|
$reflMethod->setAccessible(true);
|
||||||
|
$res = $reflMethod->invoke($formatter, array($foo, $bar), true);
|
||||||
|
|
||||||
|
restore_error_handler();
|
||||||
|
|
||||||
|
$this->assertEquals(@json_encode(array($foo, $bar)), $res);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIgnoresInvalidTypes()
|
||||||
|
{
|
||||||
|
// set up the recursion
|
||||||
|
$resource = fopen(__FILE__, 'r');
|
||||||
|
|
||||||
|
// set an error handler to assert that the error is not raised anymore
|
||||||
|
$that = $this;
|
||||||
|
set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
|
||||||
|
if (error_reporting() & $level) {
|
||||||
|
restore_error_handler();
|
||||||
|
$that->fail("$message should not be raised");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$formatter = new NormalizerFormatter();
|
||||||
|
$reflMethod = new \ReflectionMethod($formatter, 'toJson');
|
||||||
|
$reflMethod->setAccessible(true);
|
||||||
|
$res = $reflMethod->invoke($formatter, array($resource), true);
|
||||||
|
|
||||||
|
restore_error_handler();
|
||||||
|
|
||||||
|
$this->assertEquals(@json_encode(array($resource)), $res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestFooNorm
|
class TestFooNorm
|
||||||
|
@@ -108,41 +108,4 @@ class WildfireFormatterTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$wildfire->formatBatch(array($record));
|
$wildfire->formatBatch(array($record));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test issue #137 (https://github.com/Seldaek/monolog/pull/137)
|
|
||||||
*/
|
|
||||||
public function testFormatWithObjectsInContext()
|
|
||||||
{
|
|
||||||
// Set up the recursion
|
|
||||||
$foo = new \stdClass();
|
|
||||||
$bar = new \stdClass();
|
|
||||||
|
|
||||||
$foo->bar = $bar;
|
|
||||||
$bar->foo = $foo;
|
|
||||||
|
|
||||||
$record = array(
|
|
||||||
'message' => "foo",
|
|
||||||
'level' => 300,
|
|
||||||
'channel' => 'foo',
|
|
||||||
'context' => array(
|
|
||||||
'stack' => array(
|
|
||||||
array($foo),
|
|
||||||
array($bar),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'extra' => array(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set an error handler to assert that the error is not raised anymore
|
|
||||||
$that = $this;
|
|
||||||
set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
|
|
||||||
$that->fail("$message should not be raised anymore");
|
|
||||||
});
|
|
||||||
|
|
||||||
$wildfire = new WildfireFormatter();
|
|
||||||
$wildfire->format($record);
|
|
||||||
|
|
||||||
restore_error_handler();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user