PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/system/classes/Kohana/Kohana/Exception.php

https://bitbucket.org/sklyarov_ivan/trap
PHP | 282 lines | 121 code | 36 blank | 125 comment | 11 complexity | d82b3a56908ad7a8f45047acfdad2f8f MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php defined('SYSPATH') OR die('No direct access');
  2. /**
  3. * Kohana exception class. Translates exceptions using the [I18n] class.
  4. *
  5. * @package Kohana
  6. * @category Exceptions
  7. * @author Kohana Team
  8. * @copyright (c) 2008-2012 Kohana Team
  9. * @license http://kohanaframework.org/license
  10. */
  11. class Kohana_Kohana_Exception extends Exception {
  12. /**
  13. * @var array PHP error code => human readable name
  14. */
  15. public static $php_errors = array(
  16. E_ERROR => 'Fatal Error',
  17. E_USER_ERROR => 'User Error',
  18. E_PARSE => 'Parse Error',
  19. E_WARNING => 'Warning',
  20. E_USER_WARNING => 'User Warning',
  21. E_STRICT => 'Strict',
  22. E_NOTICE => 'Notice',
  23. E_RECOVERABLE_ERROR => 'Recoverable Error',
  24. E_DEPRECATED => 'Deprecated',
  25. );
  26. /**
  27. * @var string error rendering view
  28. */
  29. public static $error_view = 'kohana/error';
  30. /**
  31. * @var string error view content type
  32. */
  33. public static $error_view_content_type = 'text/html';
  34. /**
  35. * Creates a new translated exception.
  36. *
  37. * throw new Kohana_Exception('Something went terrible wrong, :user',
  38. * array(':user' => $user));
  39. *
  40. * @param string $message error message
  41. * @param array $variables translation variables
  42. * @param integer|string $code the exception code
  43. * @param Exception $previous Previous exception
  44. * @return void
  45. */
  46. public function __construct($message = "", array $variables = NULL, $code = 0, Exception $previous = NULL)
  47. {
  48. // Set the message
  49. $message = __($message, $variables);
  50. // Pass the message and integer code to the parent
  51. parent::__construct($message, (int) $code, $previous);
  52. // Save the unmodified code
  53. // @link http://bugs.php.net/39615
  54. $this->code = $code;
  55. }
  56. /**
  57. * Magic object-to-string method.
  58. *
  59. * echo $exception;
  60. *
  61. * @uses Kohana_Exception::text
  62. * @return string
  63. */
  64. public function __toString()
  65. {
  66. return Kohana_Exception::text($this);
  67. }
  68. /**
  69. * Inline exception handler, displays the error message, source of the
  70. * exception, and the stack trace of the error.
  71. *
  72. * @uses Kohana_Exception::response
  73. * @param Exception $e
  74. * @return boolean
  75. */
  76. public static function handler(Exception $e)
  77. {
  78. $response = Kohana_Exception::_handler($e);
  79. // Send the response to the browser
  80. echo $response->send_headers()->body();
  81. exit(1);
  82. }
  83. /**
  84. * Exception handler, logs the exception and generates a Response object
  85. * for display.
  86. *
  87. * @uses Kohana_Exception::response
  88. * @param Exception $e
  89. * @return boolean
  90. */
  91. public static function _handler(Exception $e)
  92. {
  93. try
  94. {
  95. // Log the exception
  96. Kohana_Exception::log($e);
  97. // Generate the response
  98. $response = Kohana_Exception::response($e);
  99. return $response;
  100. }
  101. catch (Exception $e)
  102. {
  103. /**
  104. * Things are going *really* badly for us, We now have no choice
  105. * but to bail. Hard.
  106. */
  107. // Clean the output buffer if one exists
  108. ob_get_level() AND ob_clean();
  109. // Set the Status code to 500, and Content-Type to text/plain.
  110. header('Content-Type: text/plain; charset='.Kohana::$charset, TRUE, 500);
  111. echo Kohana_Exception::text($e);
  112. exit(1);
  113. }
  114. }
  115. /**
  116. * Logs an exception.
  117. *
  118. * @uses Kohana_Exception::text
  119. * @param Exception $e
  120. * @param int $level
  121. * @return void
  122. */
  123. public static function log(Exception $e, $level = Log::EMERGENCY)
  124. {
  125. if (is_object(Kohana::$log))
  126. {
  127. // Create a text version of the exception
  128. $error = Kohana_Exception::text($e);
  129. // Add this exception to the log
  130. Kohana::$log->add($level, $error, NULL, array('exception' => $e));
  131. // Make sure the logs are written
  132. Kohana::$log->write();
  133. }
  134. }
  135. /**
  136. * Get a single line of text representing the exception:
  137. *
  138. * Error [ Code ]: Message ~ File [ Line ]
  139. *
  140. * @param Exception $e
  141. * @return string
  142. */
  143. public static function text(Exception $e)
  144. {
  145. return sprintf('%s [ %s ]: %s ~ %s [ %d ]',
  146. get_class($e), $e->getCode(), strip_tags($e->getMessage()), Debug::path($e->getFile()), $e->getLine());
  147. }
  148. /**
  149. * Get a Response object representing the exception
  150. *
  151. * @uses Kohana_Exception::text
  152. * @param Exception $e
  153. * @return Response
  154. */
  155. public static function response(Exception $e)
  156. {
  157. try
  158. {
  159. // Get the exception information
  160. $class = get_class($e);
  161. $code = $e->getCode();
  162. $message = $e->getMessage();
  163. $file = $e->getFile();
  164. $line = $e->getLine();
  165. $trace = $e->getTrace();
  166. if ( ! headers_sent())
  167. {
  168. // Make sure the proper http header is sent
  169. $http_header_status = ($e instanceof HTTP_Exception) ? $code : 500;
  170. }
  171. /**
  172. * HTTP_Exceptions are constructed in the HTTP_Exception::factory()
  173. * method. We need to remove that entry from the trace and overwrite
  174. * the variables from above.
  175. */
  176. if ($e instanceof HTTP_Exception AND $trace[0]['function'] == 'factory')
  177. {
  178. extract(array_shift($trace));
  179. }
  180. if ($e instanceof ErrorException)
  181. {
  182. /**
  183. * If XDebug is installed, and this is a fatal error,
  184. * use XDebug to generate the stack trace
  185. */
  186. if (function_exists('xdebug_get_function_stack') AND $code == E_ERROR)
  187. {
  188. $trace = array_slice(array_reverse(xdebug_get_function_stack()), 4);
  189. foreach ($trace as & $frame)
  190. {
  191. /**
  192. * XDebug pre 2.1.1 doesn't currently set the call type key
  193. * http://bugs.xdebug.org/view.php?id=695
  194. */
  195. if ( ! isset($frame['type']))
  196. {
  197. $frame['type'] = '??';
  198. }
  199. // XDebug also has a different name for the parameters array
  200. if (isset($frame['params']) AND ! isset($frame['args']))
  201. {
  202. $frame['args'] = $frame['params'];
  203. }
  204. }
  205. }
  206. if (isset(Kohana_Exception::$php_errors[$code]))
  207. {
  208. // Use the human-readable error name
  209. $code = Kohana_Exception::$php_errors[$code];
  210. }
  211. }
  212. /**
  213. * The stack trace becomes unmanageable inside PHPUnit.
  214. *
  215. * The error view ends up several GB in size, taking
  216. * serveral minutes to render.
  217. */
  218. if (defined('PHPUnit_MAIN_METHOD'))
  219. {
  220. $trace = array_slice($trace, 0, 2);
  221. }
  222. // Instantiate the error view.
  223. $view = View::factory(Kohana_Exception::$error_view, get_defined_vars());
  224. // Prepare the response object.
  225. $response = Response::factory();
  226. // Set the response status
  227. $response->status(($e instanceof HTTP_Exception) ? $e->getCode() : 500);
  228. // Set the response headers
  229. $response->headers('Content-Type', Kohana_Exception::$error_view_content_type.'; charset='.Kohana::$charset);
  230. // Set the response body
  231. $response->body($view->render());
  232. }
  233. catch (Exception $e)
  234. {
  235. /**
  236. * Things are going badly for us, Lets try to keep things under control by
  237. * generating a simpler response object.
  238. */
  239. $response = Response::factory();
  240. $response->status(500);
  241. $response->headers('Content-Type', 'text/plain');
  242. $response->body(Kohana_Exception::text($e));
  243. }
  244. return $response;
  245. }
  246. } // End Kohana_Exception