diff options
| author | xue <> | 2007-03-02 21:05:38 +0000 | 
|---|---|---|
| committer | xue <> | 2007-03-02 21:05:38 +0000 | 
| commit | 13495b462f6a618530f0f6af71fb6fad6bafed91 (patch) | |
| tree | ebe213dc568f858d16c48403948227c7e0932592 /framework/Exceptions/TErrorHandler.php | |
| parent | 56df1d34bd381e864f613cc3b72fb886dc548008 (diff) | |
Improved error display.
Diffstat (limited to 'framework/Exceptions/TErrorHandler.php')
| -rw-r--r-- | framework/Exceptions/TErrorHandler.php | 99 | 
1 files changed, 76 insertions, 23 deletions
diff --git a/framework/Exceptions/TErrorHandler.php b/framework/Exceptions/TErrorHandler.php index 14c824c9..869ccb00 100644 --- a/framework/Exceptions/TErrorHandler.php +++ b/framework/Exceptions/TErrorHandler.php @@ -207,39 +207,34 @@ class TErrorHandler extends TModule  	 */
  	protected function displayException($exception)
  	{
 -		$fileName=$exception->getFile();
 -		$errorLine=$exception->getLine();
 -		if($exception instanceof TPhpErrorException)
 +
 +		if($exception instanceof TTemplateException)
  		{
 -			// if PHP exception, we want to show the 2nd stack level context
 -			// because the 1st stack level is of little use (it's in error handler)
 -			$trace=$exception->getTrace();
 -			if(isset($trace[1]) && isset($trace[1]['file']) && isset($trace[1]['line']))
 -			{
 -				$fileName=$trace[1]['file'];
 -				$errorLine=$trace[1]['line'];
 -			}
 +			$fileName=$exception->getTemplateFile();
 +			$lines=empty($fileName)?explode("\n",$exception->getTemplateSource()):@file($fileName);
 +			$source=$this->getSourceCode($lines,$exception->getLineNumber());
 +			if($fileName==='')
 +				$fileName='---embedded template---';
 +			$errorLine=$exception->getLineNumber();
  		}
 -		$lines=file($fileName);
 -
 -		$beginLine=$errorLine-self::SOURCE_LINES>=0?$errorLine-self::SOURCE_LINES:0;
 -		$endLine=$errorLine+self::SOURCE_LINES<=count($lines)?$errorLine+self::SOURCE_LINES:count($lines);
 -
 -		$source='';
 -		for($i=$beginLine;$i<$endLine;++$i)
 +		else
  		{
 -			if($i===$errorLine-1)
 +			if(($trace=$this->getExactTrace($exception))!==null)
  			{
 -				$line=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",'    ',$lines[$i])));
 -				$source.="<div class=\"error\">".$line."</div>";
 +				$fileName=$trace['file'];
 +				$errorLine=$trace['line'];
  			}
  			else
 -				$source.=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",'    ',$lines[$i])));
 +			{
 +				$fileName=$exception->getFile();
 +				$errorLine=$exception->getLine();
 +			}
 +			$source=$this->getSourceCode(@file($fileName),$errorLine);
  		}
  		$tokens=array(
  			'%%ErrorType%%' => get_class($exception),
 -			'%%ErrorMessage%%' => htmlspecialchars($exception->getMessage()),
 +			'%%ErrorMessage%%' => $this->addLink(htmlspecialchars($exception->getMessage())),
  			'%%SourceFile%%' => htmlspecialchars($fileName).' ('.$errorLine.')',
  			'%%SourceCode%%' => $source,
  			'%%StackTrace%%' => htmlspecialchars($exception->getTraceAsString()),
 @@ -254,6 +249,64 @@ class TErrorHandler extends TModule  			die("Unable to open exception template file '$exceptionFile'.");
  		echo strtr($content,$tokens);
  	}
 +
 +	private function getExactTrace($exception)
 +	{
 +		$trace=$exception->getTrace();
 +		$result=null;
 +		// if PHP exception, we want to show the 2nd stack level context
 +		// because the 1st stack level is of little use (it's in error handler)
 +		if($exception instanceof TPhpErrorException)
 +			$result=$trace[1];
 +		else if($exception instanceof TInvalidOperationException)
 +		{
 +			// in case of getter or setter error, find out the exact file and row
 +			if(($result=$this->getPropertyAccessTrace($trace,'__get'))===null)
 +				$result=$this->getPropertyAccessTrace($trace,'__set');
 +		}
 +		if($result!==null && strpos($result['file'],': eval()\'d code')!==false)
 +			return null;
 +
 +		return $result;
 +	}
 +
 +	private function getPropertyAccessTrace($trace,$pattern)
 +	{
 +		$result=null;
 +		foreach($trace as $t)
 +		{
 +			if(isset($t['function']) && $t['function']===$pattern)
 +				$result=$t;
 +			else
 +				break;
 +		}
 +		return $result;
 +	}
 +
 +	private function getSourceCode($lines,$errorLine)
 +	{
 +		$beginLine=$errorLine-self::SOURCE_LINES>=0?$errorLine-self::SOURCE_LINES:0;
 +		$endLine=$errorLine+self::SOURCE_LINES<=count($lines)?$errorLine+self::SOURCE_LINES:count($lines);
 +
 +		$source='';
 +		for($i=$beginLine;$i<$endLine;++$i)
 +		{
 +			if($i===$errorLine-1)
 +			{
 +				$line=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",'    ',$lines[$i])));
 +				$source.="<div class=\"error\">".$line."</div>";
 +			}
 +			else
 +				$source.=htmlspecialchars(sprintf("%04d: %s",$i+1,str_replace("\t",'    ',$lines[$i])));
 +		}
 +		return $source;
 +	}
 +
 +	private function addLink($message)
 +	{
 +		$baseUrl='http://www.pradosoft.com/docs/classdoc';
 +		return preg_replace('/(T[A-Z]\w+)/',"<a href=\"$baseUrl/\${1}\" target=\"_blank\">\${1}</a>",$message);
 +	}
  }
  ?>
\ No newline at end of file  | 
