summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxue <>2006-01-27 23:56:46 +0000
committerxue <>2006-01-27 23:56:46 +0000
commitdf31a176f904b5b4c2f9505fe2fe352176728f9e (patch)
treeaeccfa86b6b1193888e49b310952c1f5757a9d6c
parent80a84e2c2cdedef934585d9ecd020dcec8c5f024 (diff)
Added error handling tutorial page.
-rw-r--r--.gitattributes3
-rw-r--r--demos/quickstart/protected/controls/TopicList.tpl1
-rw-r--r--demos/quickstart/protected/pages/Advanced/Error.page77
-rw-r--r--demos/quickstart/protected/pages/Advanced/exception.gifbin0 -> 7658 bytes
-rw-r--r--demos/quickstart/protected/pages/Advanced/exception2.gifbin0 -> 39000 bytes
-rw-r--r--framework/Exceptions/TException.php17
-rw-r--r--framework/Web/UI/TTemplateManager.php62
7 files changed, 118 insertions, 42 deletions
diff --git a/.gitattributes b/.gitattributes
index d870fb48..9b27c709 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -37,12 +37,15 @@ demos/quickstart/protected/controls/SampleLayout.tpl -text
demos/quickstart/protected/controls/TopicList.php -text
demos/quickstart/protected/controls/TopicList.tpl -text
demos/quickstart/protected/pages/Advanced/Assets.page -text
+demos/quickstart/protected/pages/Advanced/Error.page -text
demos/quickstart/protected/pages/Advanced/I18N.page -text
demos/quickstart/protected/pages/Advanced/Logging.page -text
demos/quickstart/protected/pages/Advanced/MasterContent.page -text
demos/quickstart/protected/pages/Advanced/Performance.page -text
demos/quickstart/protected/pages/Advanced/State.page -text
demos/quickstart/protected/pages/Advanced/Themes.page -text
+demos/quickstart/protected/pages/Advanced/exception.gif -text
+demos/quickstart/protected/pages/Advanced/exception2.gif -text
demos/quickstart/protected/pages/Advanced/logrouter.gif -text
demos/quickstart/protected/pages/Advanced/logrouter.vsd -text
demos/quickstart/protected/pages/Advanced/mastercontent.gif -text
diff --git a/demos/quickstart/protected/controls/TopicList.tpl b/demos/quickstart/protected/controls/TopicList.tpl
index 02aaacaf..4d24268e 100644
--- a/demos/quickstart/protected/controls/TopicList.tpl
+++ b/demos/quickstart/protected/controls/TopicList.tpl
@@ -65,6 +65,7 @@
<ul>
<li><a href="?page=Construction">Authentication and Authorization</a></li>
<li><a href="?page=Construction">ViewState Protection</a></li>
+ <li><a href="?page=Construction">Cross Site Scripting Prevention</a></li>
</ul>
</div>
diff --git a/demos/quickstart/protected/pages/Advanced/Error.page b/demos/quickstart/protected/pages/Advanced/Error.page
new file mode 100644
index 00000000..d77adfca
--- /dev/null
+++ b/demos/quickstart/protected/pages/Advanced/Error.page
@@ -0,0 +1,77 @@
+<com:TContent ID="body" >
+
+<h1>Error Handling and Reporting</h1>
+<p>
+PRADO provides a complete error handling and reporting framework based on the PHP 5 exception mechanism.
+</p>
+
+<h2>Exception Classes</h2>
+<p>
+Errors occur in a PRADO application may be classified into three categories: those caused by PHP script parsing, those caused by wrong code (such as calling an undefined function, setting an unknown property), and those caused by improper use of the Web application by client users (such as attempting to access restricted pages). PRADO is unable to deal with the first category of errors because they cannot be caughted in PHP code. PRADO provides an exception hierarchy to deal with the second and third categories.
+</p>
+<p>
+All errors in PRADO applications are represented as exceptions. The base class for all PRADO exceptions is <tt>TException</tt>. It provides the message internationalization functionality to all system exceptions. An error message may be translated into different languages according to the user browser's language preference.
+</p>
+<p>
+Exceptions raised due to improper usage of the PRADO framework inherit from <tt>TSystemException</tt>, which can be one of the following exception classes:
+</p>
+<ul>
+<li><tt>TConfigurationException</tt> - improper configuration, such as error in application configuration, control templates, etc.</li>
+<li><tt>TInvalidDataValueException</tt> - data value is incorrect or unexpected.</li>
+<li><tt>TInvalidDataTypeException</tt> - data type is incorrect or unexpected.</li>
+<li><tt>TInvalidDataFormatException</tt> - format of data is incorrect.</li>
+<li><tt>TInvalidOperationException</tt> - invalid operation request.</li>
+<li><tt>TPhpErrorException</tt> - caughtable PHP errors, warnings, notices, etc.</li>
+<li><tt>TSecurityException</tt> - errors related with security.</li>
+<li><tt>TIOException</tt> - IO operation error, such as file open failure.</li>
+<li><tt>TDBException</tt> - errors related with database operations.</li>
+<li><tt>TNotSupportedException</tt> - errors caused by requesting for unsupported feature.</li>
+<li><tt>THttpException</tt> - errors to be displayed to Web client users.</li>
+</ul>
+<p>
+Errors due to improper usage of the Web application by client users inherit from <tt>TApplicationException</tt>.
+</p>
+
+<h2>Raising Exceptions</h2>
+<p>
+Raising exceptions in PRADO has no difference than raising a normal PHP exception. The only thing matters is to raise the right exception. In general, exceptions meant to be shown to application users should use <tt>THttpException</tt>, while exceptions shown to developers should use other exception classes.
+</p>
+
+<h2>Error Capturing and Reporting</h2>
+<p>
+Exceptions raised during the runtime of PRADO applications are captured by <tt>System.Exceptions.TErrorHandler</tt> module. Different output templates are used to display the captured exceptions. <tt>THttpException</tt> is assumed to contain error messages that are meant for application end users and thus uses a specific group of templates. For all other exceptions, a common template shown as follows is used for presenting the exceptions.
+</p>
+<a href="<%~ exception2.gif %>" target="_blank"><img src="<%~ exception.gif %>" alt="exception page" style="border:0px"/></a>
+
+<h2>Customizing Error Display</h2>
+<p>
+Developers can customize the presentation of exception messages. By default, all error output templates are stored under <tt>framework/Exceptions/templates</tt>. The location can be changed by configuring <tt>TErrorHandler</tt> in application configuration,
+</p>
+<com:TTextHighlighter Language="xml" CssClass="source">
+&lt;module id="error"
+ class="TErrorHandler"&gt;
+ ErrorTemplatePath="Application.ErrorTemplates" /&gt;
+</com:TTextHighlighter>
+<p>
+<tt>THttpException</tt> uses a set of templates that are differentiated according to different <tt>StatusCode</tt> property value of <tt>THttpException</tt>. <tt>StatusCode</tt> has the same meaning as the status code in HTTP protocol. For example, a status code equal to 404 means the requested URL is not found on the server. The <tt>StatusCode</tt> value is used to select which output template to use. The output template files use the following naming convention:
+</p>
+<com:TTextHighlighter CssClass="source">
+ error<status code>-<language code>.html
+</com:TTextHighlighter>
+<p>
+where <tt>status code</tt> refers to the <tt>StatusCode</tt> property value of <tt>THttpException</tt>, and <tt>language code</tt> must be a valid language such as <tt>en</tt>, <tt>zh</tt>, <tt>fr</tt>, etc. When a <tt>THttpException</tt> is raised, PRADO will select an appropriate template for displaying the exception message. PRADO will first locate a template file whose name contains the status code and whose language is preferred by the client browser window. If such a template is not present, it will look for a template that has the same status code but without language code.
+</p>
+<p>
+The naming convention for the template files used for all other exceptions is as follows,
+</p>
+<com:TTextHighlighter CssClass="source">
+ exception-<language code>.html
+</com:TTextHighlighter>
+<p>
+Again, if the preferred language is not found, PRADO will try to use <tt>exception.html</tt>, instead.
+</p>
+<p>
+CAUTION: When saving a template file, please make sure the file is saved using UTF-8 encoding. On Windows, you may use <tt>Notepad.exe</tt> to accomplish such saving.
+</p>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/quickstart/protected/pages/Advanced/exception.gif b/demos/quickstart/protected/pages/Advanced/exception.gif
new file mode 100644
index 00000000..93b1a07f
--- /dev/null
+++ b/demos/quickstart/protected/pages/Advanced/exception.gif
Binary files differ
diff --git a/demos/quickstart/protected/pages/Advanced/exception2.gif b/demos/quickstart/protected/pages/Advanced/exception2.gif
new file mode 100644
index 00000000..5fe0e625
--- /dev/null
+++ b/demos/quickstart/protected/pages/Advanced/exception2.gif
Binary files differ
diff --git a/framework/Exceptions/TException.php b/framework/Exceptions/TException.php
index fb668458..1ad86f12 100644
--- a/framework/Exceptions/TException.php
+++ b/framework/Exceptions/TException.php
@@ -15,16 +15,19 @@
*
* TException is the base class for all PRADO exceptions.
* TException
+ * TApplicationException
* TSystemException
* TInvalidDataValueException
* TInvalidDataTypeException
+ * TInvalidDataFormatException
* TInvalidOperationException
* TConfigurationException
+ * TPhpErrorException
+ * TSecurityException
* TIOException
* TDBException
* THttpException
* TNotSupportedException
- * TApplicationException
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Revision: $ $Date: $
@@ -119,15 +122,7 @@ class TNotSupportedException extends TSystemException
{
}
-class TTemplateParsingException extends TSystemException
-{
-}
-
-class TTemplateRuntimeException extends TSystemException
-{
-}
-
-class TPhpErrorException extends TException
+class TPhpErrorException extends TSystemException
{
public function __construct($errno,$errstr,$errfile,$errline)
{
@@ -151,7 +146,7 @@ class TPhpErrorException extends TException
}
-class THttpException extends TException
+class THttpException extends TSystemException
{
private $_statusCode;
diff --git a/framework/Web/UI/TTemplateManager.php b/framework/Web/UI/TTemplateManager.php
index 07e27891..5bf0d4bb 100644
--- a/framework/Web/UI/TTemplateManager.php
+++ b/framework/Web/UI/TTemplateManager.php
@@ -420,7 +420,7 @@ class TTemplate extends TComponent implements ITemplate
* If an object has no container, its container index is -1.
*
* @param string the template string
- * @throws TTemplateParsingException if a parsing error is encountered
+ * @throws TConfigurationException if a parsing error is encountered
*/
protected function parse($input)
{
@@ -454,9 +454,9 @@ class TTemplate extends TComponent implements ITemplate
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
- throw new TTemplateParsingException('template_componenttag_invalid',"Line $line",$type,$e->getMessage());
+ throw new TConfigurationException('template_componenttag_invalid',"Line $line",$type,$e->getMessage());
else
- throw new TTemplateParsingException('template_componenttag_invalid',"{$this->_tplFile} (Line $line)",$type,$e->getMessage());
+ throw new TConfigurationException('template_componenttag_invalid',"{$this->_tplFile} (Line $line)",$type,$e->getMessage());
}
$tpl[$c++]=array($container,$type,$attributes);
if($str[strlen($str)-2]!=='/') // open tag
@@ -478,9 +478,9 @@ class TTemplate extends TComponent implements ITemplate
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
- throw new TTemplateParsingException('template_closingtag_unexpected',"Line $line","</com:$type>");
+ throw new TConfigurationException('template_closingtag_unexpected',"Line $line","</com:$type>");
else
- throw new TTemplateParsingException('template_closingtag_unexpected',"{$this->_tplFile} (Line $line)","</com:$type>");
+ throw new TConfigurationException('template_closingtag_unexpected',"{$this->_tplFile} (Line $line)","</com:$type>");
}
$name=array_pop($stack);
@@ -492,9 +492,9 @@ class TTemplate extends TComponent implements ITemplate
$tag='</com:'.$name.'>';
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
- throw new TTemplateParsingException('template_closingtag_expected',"Line $line",$tag);
+ throw new TConfigurationException('template_closingtag_expected',"Line $line",$tag);
else
- throw new TTemplateParsingException('template_closingtag_expected',"{$this->_tplFile} (Line $line)",$tag);
+ throw new TConfigurationException('template_closingtag_expected',"{$this->_tplFile} (Line $line)",$tag);
}
$container=$tpl[$container][0];
}
@@ -509,9 +509,9 @@ class TTemplate extends TComponent implements ITemplate
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
- throw new TTemplateParsingException('template_directive_nonunique',"Line $line");
+ throw new TConfigurationException('template_directive_nonunique',"Line $line");
else
- throw new TTemplateParsingException('template_directive_nonunique',"{$this->_tplFile} (Line $line)");
+ throw new TConfigurationException('template_directive_nonunique',"{$this->_tplFile} (Line $line)");
}
$this->_directive=$this->parseAttributes($match[4][0]);
}
@@ -548,9 +548,9 @@ class TTemplate extends TComponent implements ITemplate
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
- throw new TTemplateParsingException('template_closingtag_unexpected',"Line $line","</prop:$prop>");
+ throw new TConfigurationException('template_closingtag_unexpected',"Line $line","</prop:$prop>");
else
- throw new TTemplateParsingException('template_closingtag_unexpected',"{$this->_tplFile} (Line $line)","</prop:$prop>");
+ throw new TConfigurationException('template_closingtag_unexpected',"{$this->_tplFile} (Line $line)","</prop:$prop>");
}
$name=array_pop($stack);
if($name!=='@'.$prop)
@@ -561,9 +561,9 @@ class TTemplate extends TComponent implements ITemplate
$tag='</com:'.$name.'>';
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
- throw new TTemplateParsingException('template_closingtag_expected',"Line $line",$tag);
+ throw new TConfigurationException('template_closingtag_expected',"Line $line",$tag);
else
- throw new TTemplateParsingException('template_closingtag_expected',"{$this->_tplFile} (Line $line)",$tag);
+ throw new TConfigurationException('template_closingtag_expected',"{$this->_tplFile} (Line $line)",$tag);
}
if(($last=count($stack))<1 || $stack[$last-1][0]!=='@')
{
@@ -580,9 +580,9 @@ class TTemplate extends TComponent implements ITemplate
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
- throw new TTemplateParsingException('template_componenttag_invalid',"Line $line",$type,$e->getMessage());
+ throw new TConfigurationException('template_componenttag_invalid',"Line $line",$type,$e->getMessage());
else
- throw new TTemplateParsingException('template_componenttag_invalid',"{$this->_tplFile} (Line $line)",$type,$e->getMessage());
+ throw new TConfigurationException('template_componenttag_invalid',"{$this->_tplFile} (Line $line)",$type,$e->getMessage());
}
$tpl[$container][2][$prop]=$value;
$textStart=$matchEnd+1;
@@ -600,9 +600,9 @@ class TTemplate extends TComponent implements ITemplate
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
- throw new TTemplateParsingException('template_comments_forbidden',"Line $line");
+ throw new TConfigurationException('template_comments_forbidden',"Line $line");
else
- throw new TTemplateParsingException('template_comments_forbidden',"{$this->_tplFile} (Line $line)");
+ throw new TConfigurationException('template_comments_forbidden',"{$this->_tplFile} (Line $line)");
}
if($matchStart>$textStart)
$tpl[$c++]=array($container,substr($input,$textStart,$matchStart-$textStart));
@@ -612,9 +612,9 @@ class TTemplate extends TComponent implements ITemplate
{
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
- throw new TTemplateParsingException('template_matching_unexpected',"Line $line",$match);
+ throw new TConfigurationException('template_matching_unexpected',"Line $line",$match);
else
- throw new TTemplateParsingException('template_matching_unexpected',"{$this->_tplFile} (Line $line)",$match);
+ throw new TConfigurationException('template_matching_unexpected',"{$this->_tplFile} (Line $line)",$match);
}
}
if(!empty($stack))
@@ -626,9 +626,9 @@ class TTemplate extends TComponent implements ITemplate
$tag='</com:'.$name.'>';
$line=count(explode("\n",substr($input,0,$matchEnd+1)));
if($this->_tplFile===null)
- throw new TTemplateParsingException('template_closingtag_expected',"Line $line",$tag);
+ throw new TConfigurationException('template_closingtag_expected',"Line $line",$tag);
else
- throw new TTemplateParsingException('template_closingtag_expected',"{$this->_tplFile} (Line $line)",$tag);
+ throw new TConfigurationException('template_closingtag_expected',"{$this->_tplFile} (Line $line)",$tag);
}
if($textStart<strlen($input))
$tpl[$c++]=array($container,substr($input,$textStart));
@@ -697,13 +697,13 @@ class TTemplate extends TComponent implements ITemplate
// a subproperty, so the first segment must be readable
$subname=substr($name,0,$pos);
if(!is_callable(array($className,'get'.$subname)))
- throw new TTemplateParsingException('template_property_unknown',$subname);
+ throw new TConfigurationException('template_property_unknown',$subname);
}
else if(strncasecmp($name,'on',2)===0)
{
// an event
if(!is_callable(array($className,$name)))
- throw new TTemplateParsingException('template_event_unknown',$name);
+ throw new TConfigurationException('template_event_unknown',$name);
}
else
{
@@ -711,9 +711,9 @@ class TTemplate extends TComponent implements ITemplate
if(!is_callable(array($className,'set'.$name)))
{
if(is_callable(array($className,'get'.$name)))
- throw new TTemplateParsingException('template_property_readonly',$name);
+ throw new TConfigurationException('template_property_readonly',$name);
else
- throw new TTemplateParsingException('template_property_unknown',$name);
+ throw new TConfigurationException('template_property_unknown',$name);
}
}
}
@@ -723,31 +723,31 @@ class TTemplate extends TComponent implements ITemplate
foreach($attributes as $name=>$att)
{
if($att[0]===self::CONFIG_DATABIND)
- throw new TTemplateParsingException('template_databind_forbidden',$name);
+ throw new TConfigurationException('template_databind_forbidden',$name);
if(($pos=strpos($name,'.'))!==false)
{
// a subproperty, so the first segment must be readable
$subname=substr($name,0,$pos);
if(!is_callable(array($className,'get'.$subname)))
- throw new TTemplateParsingException('template_property_unknown',$subname);
+ throw new TConfigurationException('template_property_unknown',$subname);
}
else if(strncasecmp($name,'on',2)===0)
- throw new TTemplateParsingException('template_event_forbidden',$name);
+ throw new TConfigurationException('template_event_forbidden',$name);
else
{
// id is still alowed for TComponent, even if id property doesn't exist
if(strcasecmp($name,'id')!==0 && !is_callable(array($className,'set'.$name)))
{
if(is_callable(array($className,'get'.$name)))
- throw new TTemplateParsingException('template_property_readonly',$name);
+ throw new TConfigurationException('template_property_readonly',$name);
else
- throw new TTemplateParsingException('template_property_unknown',$name);
+ throw new TConfigurationException('template_property_unknown',$name);
}
}
}
}
else
- throw new TTemplateParsingException('template_component_required',$type);
+ throw new TConfigurationException('template_component_required',$type);
}
}