diff --git a/src/Monolog/Formatter/NormalizerFormatter.php b/src/Monolog/Formatter/NormalizerFormatter.php index a5c99156f..134c6879f 100644 --- a/src/Monolog/Formatter/NormalizerFormatter.php +++ b/src/Monolog/Formatter/NormalizerFormatter.php @@ -210,8 +210,14 @@ protected function normalize(mixed $data, int $depth = 0): mixed $accessor = new \ArrayObject($data); $value = (string) $accessor['__PHP_Incomplete_Class_Name']; } 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 $value */ + $value = json_decode($this->toJson($data, true), true); + } } else { // the rest is normalized by json encoding and decoding it /** @var null|scalar|array $value */ diff --git a/tests/Monolog/Formatter/NormalizerFormatterTest.php b/tests/Monolog/Formatter/NormalizerFormatterTest.php index 418b411da..0886fe8f2 100644 --- a/tests/Monolog/Formatter/NormalizerFormatterTest.php +++ b/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -131,11 +131,25 @@ public function testFormatSoapFaultException() public function testFormatToStringExceptionHandle() { $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(), ])); + $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()