mirror of
https://github.com/Seldaek/monolog.git
synced 2025-08-02 03:10:15 +02:00
Custom exception handler (#500)
Add custom exception handler to let the user change the default behavior when Monolog raise an exception while logging a record.
This commit is contained in:
@@ -133,6 +133,11 @@ class Logger implements LoggerInterface
|
|||||||
*/
|
*/
|
||||||
protected $microsecondTimestamps = true;
|
protected $microsecondTimestamps = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var callable
|
||||||
|
*/
|
||||||
|
protected $exceptionHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name The logging channel
|
* @param string $name The logging channel
|
||||||
* @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc.
|
* @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc.
|
||||||
@@ -329,16 +334,20 @@ class Logger implements LoggerInterface
|
|||||||
'extra' => array(),
|
'extra' => array(),
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($this->processors as $processor) {
|
try {
|
||||||
$record = call_user_func($processor, $record);
|
foreach ($this->processors as $processor) {
|
||||||
}
|
$record = call_user_func($processor, $record);
|
||||||
|
|
||||||
while ($handler = current($this->handlers)) {
|
|
||||||
if (true === $handler->handle($record)) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next($this->handlers);
|
while ($handler = current($this->handlers)) {
|
||||||
|
if (true === $handler->handle($record)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
next($this->handlers);
|
||||||
|
}
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
$this->handleException($ex, $record);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -501,6 +510,46 @@ class Logger implements LoggerInterface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a custom exception handler
|
||||||
|
*
|
||||||
|
* @param callable $callback
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setExceptionHandler($callback)
|
||||||
|
{
|
||||||
|
if (!is_callable($callback)) {
|
||||||
|
throw new \InvalidArgumentException('Exception handler must be valid callable (callback or object with an __invoke method), '.var_export($callback, true).' given');
|
||||||
|
}
|
||||||
|
$this->exceptionHandler = $callback;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return callable
|
||||||
|
*/
|
||||||
|
public function getExceptionHandler()
|
||||||
|
{
|
||||||
|
return $this->exceptionHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates exception management to the custom exception handler,
|
||||||
|
* or throws the exception if no custom handler is set.
|
||||||
|
*
|
||||||
|
* @param Exception $ex
|
||||||
|
* @param array $record
|
||||||
|
*/
|
||||||
|
protected function handleException(\Exception $ex, $record)
|
||||||
|
{
|
||||||
|
if ($this->exceptionHandler) {
|
||||||
|
call_user_func($this->exceptionHandler, $ex, $record);
|
||||||
|
} else {
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a log record at an arbitrary level.
|
* Adds a log record at an arbitrary level.
|
||||||
*
|
*
|
||||||
|
@@ -545,4 +545,73 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
|
|||||||
'without microseconds' => array(false, PHP_VERSION_ID >= 70100 ? 'assertNotSame' : 'assertSame'),
|
'without microseconds' => array(false, PHP_VERSION_ID >= 70100 ? 'assertNotSame' : 'assertSame'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Monolog\Logger::setExceptionHandler
|
||||||
|
*/
|
||||||
|
public function testSetExceptionHandler()
|
||||||
|
{
|
||||||
|
$logger = new Logger(__METHOD__);
|
||||||
|
$this->assertNull($logger->getExceptionHandler());
|
||||||
|
$callback = function ($ex) {
|
||||||
|
};
|
||||||
|
$logger->setExceptionHandler($callback);
|
||||||
|
$this->assertEquals($callback, $logger->getExceptionHandler());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Monolog\Logger::setExceptionHandler
|
||||||
|
* @expectedException InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function testBadExceptionHandlerType()
|
||||||
|
{
|
||||||
|
$logger = new Logger(__METHOD__);
|
||||||
|
$logger->setExceptionHandler(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Monolog\Logger::handleException
|
||||||
|
* @expectedException Exception
|
||||||
|
*/
|
||||||
|
public function testDefaultHandleException()
|
||||||
|
{
|
||||||
|
$logger = new Logger(__METHOD__);
|
||||||
|
$handler = $this->getMock('Monolog\Handler\HandlerInterface');
|
||||||
|
$handler->expects($this->any())
|
||||||
|
->method('isHandling')
|
||||||
|
->will($this->returnValue(true))
|
||||||
|
;
|
||||||
|
$handler->expects($this->any())
|
||||||
|
->method('handle')
|
||||||
|
->will($this->throwException(new \Exception('Some handler exception')))
|
||||||
|
;
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
$logger->info('test');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Monolog\Logger::handleException
|
||||||
|
* @covers Monolog\Logger::addRecord
|
||||||
|
*/
|
||||||
|
public function testCustomHandleException()
|
||||||
|
{
|
||||||
|
$logger = new Logger(__METHOD__);
|
||||||
|
$that = $this;
|
||||||
|
$logger->setExceptionHandler(function ($e, $record) use ($that) {
|
||||||
|
$that->assertEquals($e->getMessage(), 'Some handler exception');
|
||||||
|
$that->assertTrue(is_array($record));
|
||||||
|
$that->assertEquals($record['message'], 'test');
|
||||||
|
});
|
||||||
|
$handler = $this->getMock('Monolog\Handler\HandlerInterface');
|
||||||
|
$handler->expects($this->any())
|
||||||
|
->method('isHandling')
|
||||||
|
->will($this->returnValue(true))
|
||||||
|
;
|
||||||
|
$handler->expects($this->any())
|
||||||
|
->method('handle')
|
||||||
|
->will($this->throwException(new \Exception('Some handler exception')))
|
||||||
|
;
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
$logger->info('test');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user