PageRenderTime 26ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php

https://gitlab.com/jjpa2018/dashboard
PHP | 251 lines | 120 code | 33 blank | 98 comment | 10 complexity | 5263368452e9546181e214279f7932e3 MD5 | raw file
  1. <?php
  2. namespace Illuminate\Foundation\Bootstrap;
  3. use ErrorException;
  4. use Exception;
  5. use Illuminate\Contracts\Debug\ExceptionHandler;
  6. use Illuminate\Contracts\Foundation\Application;
  7. use Illuminate\Log\LogManager;
  8. use Monolog\Handler\NullHandler;
  9. use Symfony\Component\Console\Output\ConsoleOutput;
  10. use Symfony\Component\ErrorHandler\Error\FatalError;
  11. use Throwable;
  12. class HandleExceptions
  13. {
  14. /**
  15. * Reserved memory so that errors can be displayed properly on memory exhaustion.
  16. *
  17. * @var string
  18. */
  19. public static $reservedMemory;
  20. /**
  21. * The application instance.
  22. *
  23. * @var \Illuminate\Contracts\Foundation\Application
  24. */
  25. protected $app;
  26. /**
  27. * Bootstrap the given application.
  28. *
  29. * @param \Illuminate\Contracts\Foundation\Application $app
  30. * @return void
  31. */
  32. public function bootstrap(Application $app)
  33. {
  34. self::$reservedMemory = str_repeat('x', 10240);
  35. $this->app = $app;
  36. error_reporting(-1);
  37. set_error_handler([$this, 'handleError']);
  38. set_exception_handler([$this, 'handleException']);
  39. register_shutdown_function([$this, 'handleShutdown']);
  40. if (! $app->environment('testing')) {
  41. ini_set('display_errors', 'Off');
  42. }
  43. }
  44. /**
  45. * Report PHP deprecations, or convert PHP errors to ErrorException instances.
  46. *
  47. * @param int $level
  48. * @param string $message
  49. * @param string $file
  50. * @param int $line
  51. * @param array $context
  52. * @return void
  53. *
  54. * @throws \ErrorException
  55. */
  56. public function handleError($level, $message, $file = '', $line = 0, $context = [])
  57. {
  58. if (error_reporting() & $level) {
  59. if ($this->isDeprecation($level)) {
  60. return $this->handleDeprecation($message, $file, $line);
  61. }
  62. throw new ErrorException($message, 0, $level, $file, $line);
  63. }
  64. }
  65. /**
  66. * Reports a deprecation to the "deprecations" logger.
  67. *
  68. * @param string $message
  69. * @param string $file
  70. * @param int $line
  71. * @return void
  72. */
  73. public function handleDeprecation($message, $file, $line)
  74. {
  75. if (! class_exists(LogManager::class)) {
  76. return;
  77. }
  78. try {
  79. $logger = $this->app->make(LogManager::class);
  80. } catch (Exception $e) {
  81. return;
  82. }
  83. $this->ensureDeprecationLoggerIsConfigured();
  84. with($logger->channel('deprecations'), function ($log) use ($message, $file, $line) {
  85. $log->warning(sprintf('%s in %s on line %s',
  86. $message, $file, $line
  87. ));
  88. });
  89. }
  90. /**
  91. * Ensure the "deprecations" logger is configured.
  92. *
  93. * @return void
  94. */
  95. protected function ensureDeprecationLoggerIsConfigured()
  96. {
  97. with($this->app['config'], function ($config) {
  98. if ($config->get('logging.channels.deprecations')) {
  99. return;
  100. }
  101. $this->ensureNullLogDriverIsConfigured();
  102. $driver = $config->get('logging.deprecations') ?? 'null';
  103. $config->set('logging.channels.deprecations', $config->get("logging.channels.{$driver}"));
  104. });
  105. }
  106. /**
  107. * Ensure the "null" log driver is configured.
  108. *
  109. * @return void
  110. */
  111. protected function ensureNullLogDriverIsConfigured()
  112. {
  113. with($this->app['config'], function ($config) {
  114. if ($config->get('logging.channels.null')) {
  115. return;
  116. }
  117. $config->set('logging.channels.null', [
  118. 'driver' => 'monolog',
  119. 'handler' => NullHandler::class,
  120. ]);
  121. });
  122. }
  123. /**
  124. * Handle an uncaught exception from the application.
  125. *
  126. * Note: Most exceptions can be handled via the try / catch block in
  127. * the HTTP and Console kernels. But, fatal error exceptions must
  128. * be handled differently since they are not normal exceptions.
  129. *
  130. * @param \Throwable $e
  131. * @return void
  132. */
  133. public function handleException(Throwable $e)
  134. {
  135. try {
  136. self::$reservedMemory = null;
  137. $this->getExceptionHandler()->report($e);
  138. } catch (Exception $e) {
  139. //
  140. }
  141. if ($this->app->runningInConsole()) {
  142. $this->renderForConsole($e);
  143. } else {
  144. $this->renderHttpResponse($e);
  145. }
  146. }
  147. /**
  148. * Render an exception to the console.
  149. *
  150. * @param \Throwable $e
  151. * @return void
  152. */
  153. protected function renderForConsole(Throwable $e)
  154. {
  155. $this->getExceptionHandler()->renderForConsole(new ConsoleOutput, $e);
  156. }
  157. /**
  158. * Render an exception as an HTTP response and send it.
  159. *
  160. * @param \Throwable $e
  161. * @return void
  162. */
  163. protected function renderHttpResponse(Throwable $e)
  164. {
  165. $this->getExceptionHandler()->render($this->app['request'], $e)->send();
  166. }
  167. /**
  168. * Handle the PHP shutdown event.
  169. *
  170. * @return void
  171. */
  172. public function handleShutdown()
  173. {
  174. if (! is_null($error = error_get_last()) && $this->isFatal($error['type'])) {
  175. $this->handleException($this->fatalErrorFromPhpError($error, 0));
  176. }
  177. }
  178. /**
  179. * Create a new fatal error instance from an error array.
  180. *
  181. * @param array $error
  182. * @param int|null $traceOffset
  183. * @return \Symfony\Component\ErrorHandler\Error\FatalError
  184. */
  185. protected function fatalErrorFromPhpError(array $error, $traceOffset = null)
  186. {
  187. return new FatalError($error['message'], 0, $error, $traceOffset);
  188. }
  189. /**
  190. * Determine if the error level is a deprecation.
  191. *
  192. * @param int $level
  193. * @return bool
  194. */
  195. protected function isDeprecation($level)
  196. {
  197. return in_array($level, [E_DEPRECATED, E_USER_DEPRECATED]);
  198. }
  199. /**
  200. * Determine if the error type is fatal.
  201. *
  202. * @param int $type
  203. * @return bool
  204. */
  205. protected function isFatal($type)
  206. {
  207. return in_array($type, [E_COMPILE_ERROR, E_CORE_ERROR, E_ERROR, E_PARSE]);
  208. }
  209. /**
  210. * Get an instance of the exception handler.
  211. *
  212. * @return \Illuminate\Contracts\Debug\ExceptionHandler
  213. */
  214. protected function getExceptionHandler()
  215. {
  216. return $this->app->make(ExceptionHandler::class);
  217. }
  218. }