فهرست منبع

Avoid throwing an exception when the toString fails (#1868)

Vincent Langlet 1 سال پیش
والد
کامیت
c4ba76aeae
2فایلهای تغییر یافته به همراه25 افزوده شده و 5 حذف شده
  1. 8 2
      src/Monolog/Formatter/NormalizerFormatter.php
  2. 17 3
      tests/Monolog/Formatter/NormalizerFormatterTest.php

+ 8 - 2
src/Monolog/Formatter/NormalizerFormatter.php

@@ -210,8 +210,14 @@ class NormalizerFormatter implements FormatterInterface
                 $accessor = new \ArrayObject($data);
                 $accessor = new \ArrayObject($data);
                 $value = (string) $accessor['__PHP_Incomplete_Class_Name'];
                 $value = (string) $accessor['__PHP_Incomplete_Class_Name'];
             } elseif (method_exists($data, '__toString')) {
             } elseif (method_exists($data, '__toString')) {
-                /** @var string $value */
-                $value = $data->__toString();
+                try {
+                    /** @var string $value */
+                    $value = $data->__toString();
+                } catch (\Throwable) {
+                    // if the toString method is failing, use the default behavior
+                    /** @var null|scalar|array<mixed[]|scalar|null> $value */
+                    $value = json_decode($this->toJson($data, true), true);
+                }
             } else {
             } else {
                 // the rest is normalized by json encoding and decoding it
                 // the rest is normalized by json encoding and decoding it
                 /** @var null|scalar|array<mixed[]|scalar|null> $value */
                 /** @var null|scalar|array<mixed[]|scalar|null> $value */

+ 17 - 3
tests/Monolog/Formatter/NormalizerFormatterTest.php

@@ -131,11 +131,25 @@ class NormalizerFormatterTest extends TestCase
     public function testFormatToStringExceptionHandle()
     public function testFormatToStringExceptionHandle()
     {
     {
         $formatter = new NormalizerFormatter('Y-m-d');
         $formatter = new NormalizerFormatter('Y-m-d');
-        $this->expectException('RuntimeException');
-        $this->expectExceptionMessage('Could not convert to string');
-        $formatter->format($this->getRecord(context: [
+        $formatted = $formatter->format($this->getRecord(context: [
             'myObject' => new TestToStringError(),
             'myObject' => new TestToStringError(),
         ]));
         ]));
+        $this->assertEquals(
+            [
+                'level_name' => Level::Warning->getName(),
+                'level' => Level::Warning->value,
+                'channel' => 'test',
+                'message' => 'test',
+                'context' => [
+                    'myObject' => [
+                        TestToStringError::class => [],
+                    ],
+                ],
+                'datetime' => date('Y-m-d'),
+                'extra' => [],
+            ],
+            $formatted
+        );
     }
     }
 
 
     public function testBatchFormat()
     public function testBatchFormat()