/wp-content/plugins/amazon-web-services/vendor/aws/Monolog/ErrorHandler.php

https://github.com/mhoofman/wordpress-heroku · PHP · 208 lines · 147 code · 24 blank · 37 comment · 12 complexity · a9e1ab2f536a14228e203f4d68f6ba3b MD5 · raw file

  1. <?php
  2. /*
  3. * This file is part of the Monolog package.
  4. *
  5. * (c) Jordi Boggiano <j.boggiano@seld.be>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Monolog;
  11. use Psr\Log\LoggerInterface;
  12. use Psr\Log\LogLevel;
  13. /**
  14. * Monolog error handler
  15. *
  16. * A facility to enable logging of runtime errors, exceptions and fatal errors.
  17. *
  18. * Quick setup: <code>ErrorHandler::register($logger);</code>
  19. *
  20. * @author Jordi Boggiano <j.boggiano@seld.be>
  21. */
  22. class ErrorHandler
  23. {
  24. private $logger;
  25. private $previousExceptionHandler;
  26. private $uncaughtExceptionLevel;
  27. private $previousErrorHandler;
  28. private $errorLevelMap;
  29. private $fatalLevel;
  30. private $reservedMemory;
  31. private static $fatalErrors = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR);
  32. public function __construct(LoggerInterface $logger)
  33. {
  34. $this->logger = $logger;
  35. }
  36. /**
  37. * Registers a new ErrorHandler for a given Logger
  38. *
  39. * By default it will handle errors, exceptions and fatal errors
  40. *
  41. * @param LoggerInterface $logger
  42. * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling
  43. * @param int|false $exceptionLevel a LogLevel::* constant, or false to disable exception handling
  44. * @param int|false $fatalLevel a LogLevel::* constant, or false to disable fatal error handling
  45. * @return ErrorHandler
  46. */
  47. public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null)
  48. {
  49. $handler = new static($logger);
  50. if ($errorLevelMap !== false) {
  51. $handler->registerErrorHandler($errorLevelMap);
  52. }
  53. if ($exceptionLevel !== false) {
  54. $handler->registerExceptionHandler($exceptionLevel);
  55. }
  56. if ($fatalLevel !== false) {
  57. $handler->registerFatalHandler($fatalLevel);
  58. }
  59. return $handler;
  60. }
  61. public function registerExceptionHandler($level = null, $callPrevious = true)
  62. {
  63. $prev = set_exception_handler(array($this, 'handleException'));
  64. $this->uncaughtExceptionLevel = $level;
  65. if ($callPrevious && $prev) {
  66. $this->previousExceptionHandler = $prev;
  67. }
  68. }
  69. public function registerErrorHandler(array $levelMap = array(), $callPrevious = true, $errorTypes = -1)
  70. {
  71. $prev = set_error_handler(array($this, 'handleError'), $errorTypes);
  72. $this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap);
  73. if ($callPrevious) {
  74. $this->previousErrorHandler = $prev ?: true;
  75. }
  76. }
  77. public function registerFatalHandler($level = null, $reservedMemorySize = 20)
  78. {
  79. register_shutdown_function(array($this, 'handleFatalError'));
  80. $this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize);
  81. $this->fatalLevel = $level;
  82. }
  83. protected function defaultErrorLevelMap()
  84. {
  85. return array(
  86. E_ERROR => LogLevel::CRITICAL,
  87. E_WARNING => LogLevel::WARNING,
  88. E_PARSE => LogLevel::ALERT,
  89. E_NOTICE => LogLevel::NOTICE,
  90. E_CORE_ERROR => LogLevel::CRITICAL,
  91. E_CORE_WARNING => LogLevel::WARNING,
  92. E_COMPILE_ERROR => LogLevel::ALERT,
  93. E_COMPILE_WARNING => LogLevel::WARNING,
  94. E_USER_ERROR => LogLevel::ERROR,
  95. E_USER_WARNING => LogLevel::WARNING,
  96. E_USER_NOTICE => LogLevel::NOTICE,
  97. E_STRICT => LogLevel::NOTICE,
  98. E_RECOVERABLE_ERROR => LogLevel::ERROR,
  99. E_DEPRECATED => LogLevel::NOTICE,
  100. E_USER_DEPRECATED => LogLevel::NOTICE,
  101. );
  102. }
  103. /**
  104. * @private
  105. */
  106. public function handleException(\Exception $e)
  107. {
  108. $this->logger->log(
  109. $this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel,
  110. sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()),
  111. array('exception' => $e)
  112. );
  113. if ($this->previousExceptionHandler) {
  114. call_user_func($this->previousExceptionHandler, $e);
  115. }
  116. }
  117. /**
  118. * @private
  119. */
  120. public function handleError($code, $message, $file = '', $line = 0, $context = array())
  121. {
  122. if (!(error_reporting() & $code)) {
  123. return;
  124. }
  125. $level = isset($this->errorLevelMap[$code]) ? $this->errorLevelMap[$code] : LogLevel::CRITICAL;
  126. $this->logger->log($level, self::codeToString($code).': '.$message, array('code' => $code, 'message' => $message, 'file' => $file, 'line' => $line));
  127. if ($this->previousErrorHandler === true) {
  128. return false;
  129. } elseif ($this->previousErrorHandler) {
  130. return call_user_func($this->previousErrorHandler, $code, $message, $file, $line, $context);
  131. }
  132. }
  133. /**
  134. * @private
  135. */
  136. public function handleFatalError()
  137. {
  138. $this->reservedMemory = null;
  139. $lastError = error_get_last();
  140. if ($lastError && in_array($lastError['type'], self::$fatalErrors)) {
  141. $this->logger->log(
  142. $this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel,
  143. 'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'],
  144. array('code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'])
  145. );
  146. }
  147. }
  148. private static function codeToString($code)
  149. {
  150. switch ($code) {
  151. case E_ERROR:
  152. return 'E_ERROR';
  153. case E_WARNING:
  154. return 'E_WARNING';
  155. case E_PARSE:
  156. return 'E_PARSE';
  157. case E_NOTICE:
  158. return 'E_NOTICE';
  159. case E_CORE_ERROR:
  160. return 'E_CORE_ERROR';
  161. case E_CORE_WARNING:
  162. return 'E_CORE_WARNING';
  163. case E_COMPILE_ERROR:
  164. return 'E_COMPILE_ERROR';
  165. case E_COMPILE_WARNING:
  166. return 'E_COMPILE_WARNING';
  167. case E_USER_ERROR:
  168. return 'E_USER_ERROR';
  169. case E_USER_WARNING:
  170. return 'E_USER_WARNING';
  171. case E_USER_NOTICE:
  172. return 'E_USER_NOTICE';
  173. case E_STRICT:
  174. return 'E_STRICT';
  175. case E_RECOVERABLE_ERROR:
  176. return 'E_RECOVERABLE_ERROR';
  177. case E_DEPRECATED:
  178. return 'E_DEPRECATED';
  179. case E_USER_DEPRECATED:
  180. return 'E_USER_DEPRECATED';
  181. }
  182. return 'Unknown PHP error';
  183. }
  184. }