Ver Fonte

Include record message/context/extra data when throwing an exception because the log cannot be opened, fixes #1630

Jordi Boggiano há 3 anos atrás
pai
commit
c02d86ffb2

+ 1 - 1
src/Monolog/Handler/SqsHandler.php

@@ -46,7 +46,7 @@ class SqsHandler extends AbstractProcessingHandler
     protected function write(array $record): void
     {
         if (!isset($record['formatted']) || 'string' !== gettype($record['formatted'])) {
-            throw new \InvalidArgumentException('SqsHandler accepts only formatted records as a string');
+            throw new \InvalidArgumentException('SqsHandler accepts only formatted records as a string' . Utils::getRecordMessageForException($record));
         }
 
         $messageBody = $record['formatted'];

+ 3 - 3
src/Monolog/Handler/StreamHandler.php

@@ -130,7 +130,7 @@ class StreamHandler extends AbstractProcessingHandler
         if (!is_resource($this->stream)) {
             $url = $this->url;
             if (null === $url || '' === $url) {
-                throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
+                throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().' . Utils::getRecordMessageForException($record));
             }
             $this->createDir($url);
             $this->errorMessage = null;
@@ -143,7 +143,7 @@ class StreamHandler extends AbstractProcessingHandler
             if (!is_resource($stream)) {
                 $this->stream = null;
 
-                throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened in append mode: '.$this->errorMessage, $url));
+                throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened in append mode: '.$this->errorMessage, $url) . Utils::getRecordMessageForException($record));
             }
             stream_set_chunk_size($stream, $this->streamChunkSize);
             $this->stream = $stream;
@@ -151,7 +151,7 @@ class StreamHandler extends AbstractProcessingHandler
 
         $stream = $this->stream;
         if (!is_resource($stream)) {
-            throw new \LogicException('No stream was opened yet');
+            throw new \LogicException('No stream was opened yet' . Utils::getRecordMessageForException($record));
         }
 
         if ($this->useLocking) {

+ 1 - 1
src/Monolog/Handler/SwiftMailerHandler.php

@@ -83,7 +83,7 @@ class SwiftMailerHandler extends MailHandler
         }
 
         if (!$message instanceof Swift_Message) {
-            throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it');
+            throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it' . Utils::getRecordMessageForException($record));
         }
 
         if ($records) {

+ 1 - 1
src/Monolog/Handler/SyslogHandler.php

@@ -60,7 +60,7 @@ class SyslogHandler extends AbstractSyslogHandler
     protected function write(array $record): void
     {
         if (!openlog($this->ident, $this->logopts, $this->facility)) {
-            throw new \LogicException('Can\'t open syslog for ident "'.$this->ident.'" and facility "'.$this->facility.'"');
+            throw new \LogicException('Can\'t open syslog for ident "'.$this->ident.'" and facility "'.$this->facility.'"' . Utils::getRecordMessageForException($record));
         }
         syslog($this->logLevels[$record['level']], (string) $record['formatted']);
     }

+ 4 - 3
src/Monolog/Handler/TelegramBotHandler.php

@@ -13,6 +13,7 @@ namespace Monolog\Handler;
 
 use RuntimeException;
 use Monolog\Logger;
+use Monolog\Utils;
 
 /**
  * Handler send logs to Telegram using Telegram Bot API.
@@ -247,12 +248,12 @@ class TelegramBotHandler extends AbstractProcessingHandler
 
         $result = Curl\Util::execute($ch);
         if (!is_string($result)) {
-            throw new RuntimeException('Telegram API error. Description: No response');
+            throw new RuntimeException('Telegram API error. Description: No response' . Utils::getRecordMessageForException($record));
         }
         $result = json_decode($result, true);
 
         if ($result['ok'] === false) {
-            throw new RuntimeException('Telegram API error. Description: ' . $result['description']);
+            throw new RuntimeException('Telegram API error. Description: ' . $result['description'] . Utils::getRecordMessageForException($record));
         }
     }
 
@@ -265,7 +266,7 @@ class TelegramBotHandler extends AbstractProcessingHandler
     {
         $truncatedMarker = ' (...truncated)';
         if (!$this->splitLongMessages && strlen($message) > self::MAX_MESSAGE_LENGTH) {
-            return [substr($message, 0, self::MAX_MESSAGE_LENGTH - strlen($truncatedMarker)) . $truncatedMarker];
+            return [Utils::substr($message, 0, self::MAX_MESSAGE_LENGTH - strlen($truncatedMarker)) . $truncatedMarker];
         }
 
         return str_split($message, self::MAX_MESSAGE_LENGTH);

+ 21 - 0
src/Monolog/Utils.php

@@ -260,4 +260,25 @@ final class Utils
 
         return $val;
     }
+
+    /**
+     * @param array<mixed> $record
+     */
+    public static function getRecordMessageForException(array $record): string
+    {
+        $context = '';
+        $extra = '';
+        try {
+            if ($record['context']) {
+                $context = "\nContext: " . json_encode($record['context']);
+            }
+            if ($record['extra']) {
+                $extra = "\nExtra: " . json_encode($record['extra']);
+            }
+        } catch (\Throwable $e) {
+            // noop
+        }
+
+        return "\nThe exception occurred while attempting to log: " . $record['message'] . $context . $extra;
+    }
 }

+ 8 - 1
tests/Monolog/Handler/StreamHandlerTest.php

@@ -145,9 +145,16 @@ class StreamHandlerTest extends TestCase
     public function testWriteInvalidResource()
     {
         $this->expectException(\UnexpectedValueException::class);
+        $this->expectExceptionMessage('The stream or file "bogus://url" could not be opened in append mode: Failed to open stream: No such file or directory
+The exception occurred while attempting to log: test
+Context: {"foo":"bar"}
+Extra: [1,2,3]');
 
         $handler = new StreamHandler('bogus://url');
-        $handler->handle($this->getRecord());
+        $record = $this->getRecord();
+        $record['context'] = ['foo' => 'bar'];
+        $record['extra'] = [1, 2, 3];
+        $handler->handle($record);
     }
 
     /**