Преглед изворни кода

Add support for custom logging level per exception class, and set ParseError to be CRITICAL

Jordi Boggiano пре 9 година
родитељ
комит
6d2cfa63c9
2 измењених фајлова са 53 додато и 10 уклоњено
  1. 26 10
      src/Monolog/ErrorHandler.php
  2. 27 0
      tests/Monolog/ErrorHandlerTest.php

+ 26 - 10
src/Monolog/ErrorHandler.php

@@ -28,7 +28,7 @@ class ErrorHandler
     private $logger;
 
     private $previousExceptionHandler;
-    private $uncaughtExceptionLevel;
+    private $uncaughtExceptionLevelMap;
 
     private $previousErrorHandler;
     private $errorLevelMap;
@@ -49,19 +49,19 @@ class ErrorHandler
      * By default it will handle errors, exceptions and fatal errors
      *
      * @param  LoggerInterface $logger
-     * @param  array|false     $errorLevelMap  an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling
-     * @param  int|false       $exceptionLevel a LogLevel::* constant, or false to disable exception handling
-     * @param  int|false       $fatalLevel     a LogLevel::* constant, or false to disable fatal error handling
+     * @param  array|false     $errorLevelMap     an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling
+     * @param  array|false     $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling
+     * @param  int|false       $fatalLevel        a LogLevel::* constant, or false to disable fatal error handling
      * @return ErrorHandler
      */
-    public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null)
+    public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevelMap = array(), $fatalLevel = null)
     {
         $handler = new static($logger);
         if ($errorLevelMap !== false) {
             $handler->registerErrorHandler($errorLevelMap);
         }
-        if ($exceptionLevel !== false) {
-            $handler->registerExceptionHandler($exceptionLevel);
+        if ($exceptionLevelMap !== false) {
+            $handler->registerExceptionHandler($exceptionLevelMap);
         }
         if ($fatalLevel !== false) {
             $handler->registerFatalHandler($fatalLevel);
@@ -70,10 +70,10 @@ class ErrorHandler
         return $handler;
     }
 
-    public function registerExceptionHandler($level = null, $callPrevious = true)
+    public function registerExceptionHandler($levelMap = array(), $callPrevious = true)
     {
         $prev = set_exception_handler(array($this, 'handleException'));
-        $this->uncaughtExceptionLevel = $level;
+        $this->uncaughtExceptionLevelMap = array_replace($this->defaultExceptionLevelMap(), $levelMap);
         if ($callPrevious && $prev) {
             $this->previousExceptionHandler = $prev;
         }
@@ -97,6 +97,14 @@ class ErrorHandler
         $this->hasFatalErrorHandler = true;
     }
 
+    protected function defaultExceptionLevelMap()
+    {
+        return array(
+            'ParseError' => LogLevel::CRITICAL,
+            'Throwable' => LogLevel::ERROR,
+        );
+    }
+
     protected function defaultErrorLevelMap()
     {
         return array(
@@ -123,8 +131,16 @@ class ErrorHandler
      */
     public function handleException($e)
     {
+        $level = LogLevel::ERROR;
+        foreach ($this->uncaughtExceptionLevelMap as $class => $candidate) {
+            if ($e instanceof $class) {
+                $level = $candidate;
+                break;
+            }
+        }
+
         $this->logger->log(
-            $this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel,
+            $level,
             sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()),
             array('exception' => $e)
         );

+ 27 - 0
tests/Monolog/ErrorHandlerTest.php

@@ -28,4 +28,31 @@ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
         $this->assertCount(2, $handler->getRecords());
         $this->assertTrue($handler->hasEmergencyRecords());
     }
+
+    public function testHandleException()
+    {
+        $logger = new Logger('test', array($handler = new TestHandler));
+        $errHandler = new ErrorHandler($logger);
+
+        $errHandler->registerExceptionHandler(array('Monolog\CustomTestException' => Logger::ALERT, 'Throwable' => Logger::WARNING), false);
+
+        try {
+            throw new CustomCustomException();
+            $this->assertCount(1, $handler->getRecords());
+            $this->assertTrue($handler->hasAlertRecords());
+        } catch (\Throwable $e) {}
+        try {
+            throw new CustomTestException();
+            $this->assertCount(2, $handler->getRecords());
+            $this->assertTrue($handler->hasAlertRecords());
+        } catch (\Throwable $e) {}
+        try {
+            throw new RuntimeException();
+            $this->assertCount(3, $handler->getRecords());
+            $this->assertTrue($handler->hasWarningRecords());
+        } catch (\Throwable $e) {}
+    }
 }
+
+class CustomTestException extends \Exception {}
+class CustomCustomException extends CustomTestException {}