summaryrefslogtreecommitdiff
path: root/framework/Exceptions/TErrorHandler.php
diff options
context:
space:
mode:
Diffstat (limited to 'framework/Exceptions/TErrorHandler.php')
-rw-r--r--framework/Exceptions/TErrorHandler.php99
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