| Total Complexity | 47 |
| Total Lines | 202 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like ErrorHandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ErrorHandler, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 27 | class ErrorHandler |
||
| 28 | { |
||
| 29 | private $logger; |
||
| 30 | |||
| 31 | private $previousExceptionHandler; |
||
| 32 | private $uncaughtExceptionLevel; |
||
| 33 | |||
| 34 | private $previousErrorHandler; |
||
| 35 | private $errorLevelMap; |
||
| 36 | private $handleOnlyReportedErrors; |
||
| 37 | |||
| 38 | private $hasFatalErrorHandler; |
||
| 39 | private $fatalLevel; |
||
| 40 | private $reservedMemory; |
||
| 41 | private static $fatalErrors = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR); |
||
| 42 | |||
| 43 | public function __construct(LoggerInterface $logger) |
||
| 44 | { |
||
| 45 | $this->logger = $logger; |
||
| 46 | } |
||
| 47 | |||
| 48 | /** |
||
| 49 | * Registers a new ErrorHandler for a given Logger |
||
| 50 | * |
||
| 51 | * By default it will handle errors, exceptions and fatal errors |
||
| 52 | * |
||
| 53 | * @param LoggerInterface $logger |
||
| 54 | * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling |
||
| 55 | * @param int|false $exceptionLevel a LogLevel::* constant, or false to disable exception handling |
||
| 56 | * @param int|false $fatalLevel a LogLevel::* constant, or false to disable fatal error handling |
||
| 57 | * @return ErrorHandler |
||
| 58 | */ |
||
| 59 | public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null) |
||
| 60 | { |
||
| 61 | //Forces the autoloader to run for LogLevel. Fixes an autoload issue at compile-time on PHP5.3. See https://github.com/Seldaek/monolog/pull/929 |
||
| 62 | class_exists('\\Psr\\Log\\LogLevel', true); |
||
| 63 | |||
| 64 | $handler = new static($logger); |
||
| 65 | if ($errorLevelMap !== false) { |
||
| 66 | $handler->registerErrorHandler($errorLevelMap); |
||
| 67 | } |
||
| 68 | if ($exceptionLevel !== false) { |
||
| 69 | $handler->registerExceptionHandler($exceptionLevel); |
||
| 70 | } |
||
| 71 | if ($fatalLevel !== false) { |
||
| 72 | $handler->registerFatalHandler($fatalLevel); |
||
| 73 | } |
||
| 74 | |||
| 75 | return $handler; |
||
| 76 | } |
||
| 77 | |||
| 78 | public function registerExceptionHandler($level = null, $callPrevious = true) |
||
| 79 | { |
||
| 80 | $prev = set_exception_handler(array($this, 'handleException')); |
||
| 81 | $this->uncaughtExceptionLevel = $level; |
||
| 82 | if ($callPrevious && $prev) { |
||
| 83 | $this->previousExceptionHandler = $prev; |
||
| 84 | } |
||
| 85 | } |
||
| 86 | |||
| 87 | public function registerErrorHandler(array $levelMap = array(), $callPrevious = true, $errorTypes = -1, $handleOnlyReportedErrors = true) |
||
| 88 | { |
||
| 89 | $prev = set_error_handler(array($this, 'handleError'), $errorTypes); |
||
| 90 | $this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap); |
||
| 91 | if ($callPrevious) { |
||
| 92 | $this->previousErrorHandler = $prev ?: true; |
||
| 93 | } |
||
| 94 | |||
| 95 | $this->handleOnlyReportedErrors = $handleOnlyReportedErrors; |
||
| 96 | } |
||
| 97 | |||
| 98 | public function registerFatalHandler($level = null, $reservedMemorySize = 20) |
||
| 99 | { |
||
| 100 | register_shutdown_function(array($this, 'handleFatalError')); |
||
| 101 | |||
| 102 | $this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize); |
||
| 103 | $this->fatalLevel = $level; |
||
| 104 | $this->hasFatalErrorHandler = true; |
||
| 105 | } |
||
| 106 | |||
| 107 | protected function defaultErrorLevelMap() |
||
| 108 | { |
||
| 109 | return array( |
||
| 110 | E_ERROR => LogLevel::CRITICAL, |
||
| 111 | E_WARNING => LogLevel::WARNING, |
||
| 112 | E_PARSE => LogLevel::ALERT, |
||
| 113 | E_NOTICE => LogLevel::NOTICE, |
||
| 114 | E_CORE_ERROR => LogLevel::CRITICAL, |
||
| 115 | E_CORE_WARNING => LogLevel::WARNING, |
||
| 116 | E_COMPILE_ERROR => LogLevel::ALERT, |
||
| 117 | E_COMPILE_WARNING => LogLevel::WARNING, |
||
| 118 | E_USER_ERROR => LogLevel::ERROR, |
||
| 119 | E_USER_WARNING => LogLevel::WARNING, |
||
| 120 | E_USER_NOTICE => LogLevel::NOTICE, |
||
| 121 | E_STRICT => LogLevel::NOTICE, |
||
| 122 | E_RECOVERABLE_ERROR => LogLevel::ERROR, |
||
| 123 | E_DEPRECATED => LogLevel::NOTICE, |
||
| 124 | E_USER_DEPRECATED => LogLevel::NOTICE, |
||
| 125 | ); |
||
| 126 | } |
||
| 127 | |||
| 128 | /** |
||
| 129 | * @private |
||
| 130 | */ |
||
| 131 | public function handleException($e) |
||
| 132 | { |
||
| 133 | $this->logger->log( |
||
| 134 | $this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel, |
||
| 135 | sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), |
||
| 136 | array('exception' => $e) |
||
| 137 | ); |
||
| 138 | |||
| 139 | if ($this->previousExceptionHandler) { |
||
| 140 | call_user_func($this->previousExceptionHandler, $e); |
||
| 141 | } |
||
| 142 | |||
| 143 | exit(255); |
||
|
|
|||
| 144 | } |
||
| 145 | |||
| 146 | /** |
||
| 147 | * @private |
||
| 148 | */ |
||
| 149 | public function handleError($code, $message, $file = '', $line = 0, $context = array()) |
||
| 165 | } |
||
| 166 | } |
||
| 167 | |||
| 168 | /** |
||
| 169 | * @private |
||
| 170 | */ |
||
| 171 | public function handleFatalError() |
||
| 187 | } |
||
| 188 | } |
||
| 189 | } |
||
| 190 | } |
||
| 191 | } |
||
| 192 | |||
| 193 | private static function codeToString($code) |
||
| 229 | } |
||
| 230 | } |
||
| 231 |
In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.