ErrorHandler.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. /**
  3. * PHP 5
  4. *
  5. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  6. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7. *
  8. * Licensed under The MIT License
  9. * For full copyright and license information, please see the LICENSE.txt
  10. * Redistributions of files must retain the above copyright notice.
  11. *
  12. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  13. * @link http://cakephp.org CakePHP(tm) Project
  14. * @since CakePHP(tm) v 0.10.5.1732
  15. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  16. */
  17. namespace Cake\Error;
  18. use Cake\Core\App;
  19. use Cake\Utility\Debugger;
  20. /**
  21. *
  22. * Error Handler provides basic error and exception handling for your application. It captures and
  23. * handles all unhandled exceptions and errors. Displays helpful framework errors when debug > 1.
  24. *
  25. * ### Uncaught exceptions
  26. *
  27. * When debug < 1 a CakeException will render 404 or 500 errors. If an uncaught exception is thrown
  28. * and it is a type that ErrorHandler does not know about it will be treated as a 500 error.
  29. *
  30. * ### Implementing application specific exception handling
  31. *
  32. * You can implement application specific exception handling in one of a few ways. Each approach
  33. * gives you different amounts of control over the exception handling process.
  34. *
  35. * - Modify App/Config/error.php and setup custom exception handling.
  36. * - Use the `exceptionRenderer` option to inject an Exception renderer. This will
  37. * let you keep the existing handling logic but override the rendering logic.
  38. *
  39. * #### Create your own Exception handler
  40. *
  41. * This gives you full control over the exception handling process. The class you choose should be
  42. * loaded in your app/Config/error.php and registered as the default exception handler.
  43. *
  44. * #### Using a custom renderer with `exceptionRenderer`
  45. *
  46. * If you don't want to take control of the exception handling, but want to change how exceptions are
  47. * rendered you can use `exceptionRenderer` option to choose a class to render exception pages. By default
  48. * `Cake\Error\ExceptionRenderer` is used. Your custom exception renderer class should be placed in app/Error.
  49. *
  50. * Your custom renderer should expect an exception in its constructor, and implement a render method.
  51. * Failing to do so will cause additional errors.
  52. *
  53. * #### Logging exceptions
  54. *
  55. * Using the built-in exception handling, you can log all the exceptions
  56. * that are dealt with by ErrorHandler by setting `log` option to true in your App/Config/error.php.
  57. * Enabling this will log every exception to Log and the configured loggers.
  58. *
  59. * ### PHP errors
  60. *
  61. * Error handler also provides the built in features for handling php errors (trigger_error).
  62. * While in debug mode, errors will be output to the screen using debugger. While in production mode,
  63. * errors will be logged to Log. You can control which errors are logged by setting
  64. * `errorLevel` option in App/Config/error.php.
  65. *
  66. * #### Logging errors
  67. *
  68. * When ErrorHandler is used for handling errors, you can enable error logging by setting the `log`
  69. * option to true. This will log all errors to the configured log handlers.
  70. *
  71. * #### Controlling what errors are logged/displayed
  72. *
  73. * You can control which errors are logged / displayed by ErrorHandler by setting `errorLevel`. Setting this
  74. * to one or a combination of a few of the E_* constants will only enable the specified errors:
  75. *
  76. * `$options['errorLevel'] = E_ALL & ~E_NOTICE;`
  77. *
  78. * Would enable handling for all non Notice errors.
  79. *
  80. * @see ExceptionRenderer for more information on how to customize exception rendering.
  81. */
  82. class ErrorHandler extends BaseErrorHandler {
  83. /**
  84. * Options to use for the Error handling.
  85. *
  86. * @var array
  87. */
  88. protected $_options = [];
  89. /**
  90. * Constructor
  91. *
  92. * @param array $options The options for error handling.
  93. */
  94. public function __construct($options = []) {
  95. $defaults = [
  96. 'log' => true,
  97. 'trace' => false,
  98. 'exceptionRenderer' => 'Cake\Error\ExceptionRenderer',
  99. ];
  100. $this->_options = array_merge($defaults, $options);
  101. }
  102. /**
  103. * Display an error.
  104. *
  105. * Template method of BaseErrorHandler.
  106. *
  107. * Only when debug > 2 will a formatted error be displayed.
  108. *
  109. * @param array $error An array of error data.
  110. * @param boolean $debug Whether or not the app is in debug mode.
  111. * @return void
  112. */
  113. protected function _displayError($error, $debug) {
  114. if (!$debug) {
  115. return;
  116. }
  117. Debugger::getInstance()->outputError($error);
  118. }
  119. /**
  120. * Displays an exception response body.
  121. *
  122. * @param \Exception $exception The exception to display
  123. * @return void
  124. * @throws \Exception When the chosen exception renderer is invalid.
  125. */
  126. protected function _displayException($exception) {
  127. $renderer = App::classname($this->_options['exceptionRenderer'], 'Error');
  128. try {
  129. if (!$renderer) {
  130. throw new \Exception("$renderer is an invalid class.");
  131. }
  132. $error = new $renderer($exception);
  133. $error->render();
  134. } catch (\Exception $e) {
  135. // Disable trace for internal errors.
  136. $this->_options['trace'] = false;
  137. $message = sprintf("[%s] %s\n%s", // Keeping same message format
  138. get_class($e),
  139. $e->getMessage(),
  140. $e->getTraceAsString()
  141. );
  142. trigger_error($message, E_USER_ERROR);
  143. }
  144. }
  145. }