PageRenderTime 37ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/oiclient/data/symfony/exception/sfException.class.php

http://openirudi.googlecode.com/
PHP | 286 lines | 180 code | 32 blank | 74 comment | 33 complexity | 8c997055ef690a1cd517b542620f0bd3 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
  5. * (c) 2004-2006 Sean Kerr <sean@code-box.org>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. /**
  11. * sfException is the base class for all symfony related exceptions and
  12. * provides an additional method for printing up a detailed view of an
  13. * exception.
  14. *
  15. * @package symfony
  16. * @subpackage exception
  17. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  18. * @author Sean Kerr <sean@code-box.org>
  19. * @version SVN: $Id: sfException.class.php 11837 2008-09-29 08:12:42Z fabien $
  20. */
  21. class sfException extends Exception
  22. {
  23. protected
  24. $wrappedException = null;
  25. /**
  26. * Wraps an Exception.
  27. *
  28. * @param Exception $e An Exception instance
  29. *
  30. * @return sfException An sfException instance that wraps the given Exception object
  31. */
  32. static public function createFromException(Exception $e)
  33. {
  34. $exception = new sfException(sprintf('Wrapped %s: %s', get_class($e), $e->getMessage()));
  35. $exception->setWrappedException($e);
  36. return $exception;
  37. }
  38. /**
  39. * Changes the wrapped exception.
  40. *
  41. * @param Exception $e An Exception instance
  42. */
  43. public function setWrappedException(Exception $e)
  44. {
  45. $this->wrappedException = $e;
  46. }
  47. /**
  48. * Prints the stack trace for this exception.
  49. */
  50. public function printStackTrace()
  51. {
  52. $exception = is_null($this->wrappedException) ? $this : $this->wrappedException;
  53. if (!sfConfig::get('sf_test'))
  54. {
  55. // log all exceptions in php log
  56. error_log($exception->getMessage());
  57. // clean current output buffer
  58. while (ob_get_level())
  59. {
  60. if (!ob_end_clean())
  61. {
  62. break;
  63. }
  64. }
  65. ob_start(sfConfig::get('sf_compressed') ? 'ob_gzhandler' : '');
  66. header('HTTP/1.1 500 Internal Server Error');
  67. }
  68. try
  69. {
  70. $this->outputStackTrace($exception);
  71. }
  72. catch (Exception $e)
  73. {
  74. }
  75. if (!sfConfig::get('sf_test'))
  76. {
  77. exit(1);
  78. }
  79. }
  80. /**
  81. * Gets the stack trace for this exception.
  82. */
  83. static protected function outputStackTrace($exception)
  84. {
  85. if (class_exists('sfContext', false) && sfContext::hasInstance())
  86. {
  87. $dispatcher = sfContext::getInstance()->getEventDispatcher();
  88. if (sfConfig::get('sf_logging_enabled'))
  89. {
  90. $dispatcher->notify(new sfEvent($exception, 'application.log', array($exception->getMessage(), 'priority' => sfLogger::ERR)));
  91. }
  92. $event = $dispatcher->notifyUntil(new sfEvent($exception, 'application.throw_exception'));
  93. if ($event->isProcessed())
  94. {
  95. return;
  96. }
  97. }
  98. // send an error 500 if not in debug mode
  99. if (!sfConfig::get('sf_debug'))
  100. {
  101. $files = array();
  102. // first check for app/project specific error page, can only do this if we have a context
  103. if (sfConfig::get('sf_app_config_dir'))
  104. {
  105. $files[] = sfConfig::get('sf_app_config_dir').'/error_500.php';
  106. }
  107. $files[] = sfConfig::get('sf_config_dir').'/error_500.php';
  108. $files[] = sfConfig::get('sf_web_dir').'/errors/error500.php';
  109. $files[] = dirname(__FILE__).'/data/error500.php';
  110. foreach ($files as $file)
  111. {
  112. if (is_readable($file))
  113. {
  114. include $file;
  115. return;
  116. }
  117. }
  118. }
  119. $message = null !== $exception->getMessage() ? $exception->getMessage() : 'n/a';
  120. $name = get_class($exception);
  121. $format = 0 == strncasecmp(PHP_SAPI, 'cli', 3) ? 'plain' : 'html';
  122. $traces = self::getTraces($exception, $format);
  123. // dump main objects values
  124. $sf_settings = '';
  125. $settingsTable = $requestTable = $responseTable = $globalsTable = $userTable = '';
  126. if (class_exists('sfContext', false) && sfContext::hasInstance())
  127. {
  128. $context = sfContext::getInstance();
  129. $settingsTable = self::formatArrayAsHtml(sfDebug::settingsAsArray());
  130. $requestTable = self::formatArrayAsHtml(sfDebug::requestAsArray($context->getRequest()));
  131. $responseTable = self::formatArrayAsHtml(sfDebug::responseAsArray($context->getResponse()));
  132. $userTable = self::formatArrayAsHtml(sfDebug::userAsArray($context->getUser()));
  133. $globalsTable = self::formatArrayAsHtml(sfDebug::globalsAsArray());
  134. }
  135. include dirname(__FILE__).'/data/exception.'.($format == 'html' ? 'php' : 'txt');
  136. }
  137. /**
  138. * Returns an array of exception traces.
  139. *
  140. * @param Exception $exception An Exception implementation instance
  141. * @param string $format The trace format (plain or html)
  142. *
  143. * @return array An array of traces
  144. */
  145. static public function getTraces($exception, $format = 'plain')
  146. {
  147. $traceData = $exception->getTrace();
  148. array_unshift($traceData, array(
  149. 'function' => '',
  150. 'file' => $exception->getFile() != null ? $exception->getFile() : 'n/a',
  151. 'line' => $exception->getLine() != null ? $exception->getLine() : 'n/a',
  152. 'args' => array(),
  153. ));
  154. $traces = array();
  155. if ($format == 'html')
  156. {
  157. $lineFormat = 'at <strong>%s%s%s</strong>(%s)<br />in <em>%s</em> line %s <a href="#" onclick="toggle(\'%s\'); return false;">...</a><br /><ul id="%s" style="display: %s">%s</ul>';
  158. }
  159. else
  160. {
  161. $lineFormat = 'at %s%s%s(%s) in %s line %s';
  162. }
  163. for ($i = 0, $count = count($traceData); $i < $count; $i++)
  164. {
  165. $line = isset($traceData[$i]['line']) ? $traceData[$i]['line'] : 'n/a';
  166. $file = isset($traceData[$i]['file']) ? $traceData[$i]['file'] : 'n/a';
  167. $shortFile = preg_replace(array('#^'.preg_quote(sfConfig::get('sf_root_dir')).'#', '#^'.preg_quote(realpath(sfConfig::get('sf_symfony_lib_dir'))).'#'), array('SF_ROOT_DIR', 'SF_SYMFONY_LIB_DIR'), $file);
  168. $args = isset($traceData[$i]['args']) ? $traceData[$i]['args'] : array();
  169. $traces[] = sprintf($lineFormat,
  170. (isset($traceData[$i]['class']) ? $traceData[$i]['class'] : ''),
  171. (isset($traceData[$i]['type']) ? $traceData[$i]['type'] : ''),
  172. $traceData[$i]['function'],
  173. self::formatArgs($args, false, $format),
  174. $shortFile,
  175. $line,
  176. 'trace_'.$i,
  177. 'trace_'.$i,
  178. $i == 0 ? 'block' : 'none',
  179. self::fileExcerpt($file, $line)
  180. );
  181. }
  182. return $traces;
  183. }
  184. /**
  185. * Returns an HTML version of an array as YAML.
  186. *
  187. * @param array $values The values array
  188. *
  189. * @return string An HTML string
  190. */
  191. static protected function formatArrayAsHtml($values)
  192. {
  193. return '<pre>'.@sfYaml::Dump($values).'</pre>';
  194. }
  195. /**
  196. * Returns an excerpt of a code file around the given line number.
  197. *
  198. * @param string $file A file path
  199. * @param int $line The selected line number
  200. *
  201. * @return string An HTML string
  202. */
  203. static protected function fileExcerpt($file, $line)
  204. {
  205. if (is_readable($file))
  206. {
  207. $content = preg_split('#<br />#', highlight_file($file, true));
  208. $lines = array();
  209. for ($i = max($line - 3, 1), $max = min($line + 3, count($content)); $i <= $max; $i++)
  210. {
  211. $lines[] = '<li'.($i == $line ? ' class="selected"' : '').'>'.$content[$i - 1].'</li>';
  212. }
  213. return '<ol start="'.max($line - 3, 1).'">'.implode("\n", $lines).'</ol>';
  214. }
  215. }
  216. /**
  217. * Formats an array as a string.
  218. *
  219. * @param array $args The argument array
  220. * @param boolean $single
  221. * @param string $format The format string (html or plain)
  222. *
  223. * @return string
  224. */
  225. static protected function formatArgs($args, $single = false, $format = 'html')
  226. {
  227. $result = array();
  228. $single and $args = array($args);
  229. foreach ($args as $key => $value)
  230. {
  231. if (is_object($value))
  232. {
  233. $result[] = ($format == 'html' ? '<em>object</em>' : 'object').'(\''.get_class($value).'\')';
  234. }
  235. else if (is_array($value))
  236. {
  237. $result[] = ($format == 'html' ? '<em>array</em>' : 'array').'('.self::formatArgs($value).')';
  238. }
  239. else if ($value === null)
  240. {
  241. $result[] = '<em>null</em>';
  242. }
  243. else if (!is_int($key))
  244. {
  245. $result[] = "'$key' =&gt; '$value'";
  246. }
  247. else
  248. {
  249. $result[] = "'".$value."'";
  250. }
  251. }
  252. return implode(', ', $result);
  253. }
  254. }