diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b3ffa87..5ba49bea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - New #104: Add new static methods `Logger::assertLevelIsValid()`, `Logger::assertLevelIsString()` and `Logger::assertLevelIsSupported()` (@vjik) - Chg #104: Deprecate method `Logger::validateLevel()` (@vjik) +- Bug #98: Fix error on formatting trace, when it doesn't contain "file" and "line" (@vjik) ## 2.0.0 May 22, 2022 diff --git a/src/Message/Formatter.php b/src/Message/Formatter.php index e7979c62..232259ce 100644 --- a/src/Message/Formatter.php +++ b/src/Message/Formatter.php @@ -240,7 +240,23 @@ private function getTrace(Message $message): string } $lines = array_map( - static fn (array $trace): string => "in {$trace['file']}:{$trace['line']}", + static function (array $trace): string { + $file = $trace['file'] ?? null; + $line = $trace['line'] ?? null; + if (is_string($file) && is_int($line)) { + return 'in ' . $file . ':' . $line; + } + + $class = $trace['class'] ?? null; + $function = $trace['function'] ?? null; + if (is_string($function)) { + return is_string($class) + ? ($class . ':' . $function) + : $function; + } + + return '???'; + }, $traces, ); diff --git a/tests/Message/FormatterTest.php b/tests/Message/FormatterTest.php index 94d81377..1fc74bb0 100644 --- a/tests/Message/FormatterTest.php +++ b/tests/Message/FormatterTest.php @@ -156,19 +156,59 @@ public function testFormatWithContextAndSetFormat(): void $this->assertSame($expected, $this->formatter->format($message, [])); } - public function testFormatWithTraceInContext(): void + public static function dataFormatWithTraceInContext(): array + { + return [ + 'file-and-line' => [ + 'in /path/to/file:99', + [ + 'file' => '/path/to/file', + 'line' => 99, + ], + ], + 'function-and-class' => [ + 'App\HomePageAction:App\{closure}', + [ + 'function' => 'App\{closure}', + 'class' => 'App\HomePageAction', + 'object' => new stdClass(), + 'type' => '->', + 'args' => [], + ], + ], + 'function' => [ + 'App\{closure}', + [ + 'function' => 'App\{closure}', + 'type' => '->', + 'args' => [], + ], + ], + 'unsupported' => [ + '???', + [ + 'something' => 'strange', + ], + ], + ]; + } + + /** + * @dataProvider dataFormatWithTraceInContext + */ + public function testFormatWithTraceInContext(string $expectedTrace, array $traceItem): void { $timestamp = 1_508_160_390; $this->formatter->setTimestampFormat('Y-m-d H:i:s'); $message = new Message( LogLevel::INFO, 'message', - ['category' => 'app', 'time' => $timestamp, 'trace' => [['file' => '/path/to/file', 'line' => 99]]], + ['category' => 'app', 'time' => $timestamp, 'trace' => [$traceItem]], ); $expected = "2017-10-16 13:26:30 [info][app] message\n\nMessage context:\n\n" - . "trace:\n in /path/to/file:99\n" - . "category: 'app'\ntime: {$timestamp}\n"; + . "trace:\n $expectedTrace\n" + . "category: 'app'\ntime: $timestamp\n"; $this->assertSame($expected, $this->formatter->format($message, [])); }