diff --git a/src/Monolog/Handler/SqsHandler.php b/src/Monolog/Handler/SqsHandler.php index dc1dcb42..dcf282b4 100644 --- a/src/Monolog/Handler/SqsHandler.php +++ b/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']; diff --git a/src/Monolog/Handler/StreamHandler.php b/src/Monolog/Handler/StreamHandler.php index 2531d41b..e6c79569 100644 --- a/src/Monolog/Handler/StreamHandler.php +++ b/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) { diff --git a/src/Monolog/Handler/SwiftMailerHandler.php b/src/Monolog/Handler/SwiftMailerHandler.php index b3fedea5..7d6b7b68 100644 --- a/src/Monolog/Handler/SwiftMailerHandler.php +++ b/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) { diff --git a/src/Monolog/Handler/SyslogHandler.php b/src/Monolog/Handler/SyslogHandler.php index 4951f66a..0acf6c2e 100644 --- a/src/Monolog/Handler/SyslogHandler.php +++ b/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']); } diff --git a/src/Monolog/Handler/TelegramBotHandler.php b/src/Monolog/Handler/TelegramBotHandler.php index e8c818fe..0f935808 100644 --- a/src/Monolog/Handler/TelegramBotHandler.php +++ b/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); diff --git a/src/Monolog/Utils.php b/src/Monolog/Utils.php index d3e7ad09..726c9819 100644 --- a/src/Monolog/Utils.php +++ b/src/Monolog/Utils.php @@ -260,4 +260,25 @@ final class Utils return $val; } + + /** + * @param array $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; + } } diff --git a/tests/Monolog/Handler/StreamHandlerTest.php b/tests/Monolog/Handler/StreamHandlerTest.php index 275aa955..2b2f6a67 100644 --- a/tests/Monolog/Handler/StreamHandlerTest.php +++ b/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); } /**