Web:Extend uses various exceptions for error handling, including SPL exceptions and a few others. The exceptions thrown by a function are listed in its docComment and can be found in the API. It is good practice to catch these exceptions and display a meaningful message to the user. If you don't, however, Web:Extend will handle it, as described in this article.
There's 2 kinds of exceptions: logical and runtime. The logical exceptions are thrown when something is wrong with the application itself. For example: a parameter has a wrong type. The runtime exceptions can only be detected at runtime: for example the user sent an unexpected value.
The following two tables contain all the exceptions used by the framework (but not necessarily defined by default).
Table 3.1. Logical exceptions
| Name | Description |
|---|---|
BadFunctionCallException | Exception thrown when a function call was illegal. |
BadMethodCallException | Exception thrown when a method call was illegal. |
BadXMLException | Exception thrown when an XML doesn't follow strictly its DTD schema. |
DomainException | Exception that denotes a value not in the valid domain was used. |
DoubleFaultException | Exception thrown in the exception handling code. |
FileNotFoundException | Exception thrown when a required file is missing. |
IllegalStateException | Exception thrown when a method is called and the object isn't in the right state (example: not initialized). |
InvalidArgumentException | Exception that denotes invalid arguments were passed. |
LengthException | Exception thrown when a parameter exceeds the allowed length. |
OutOfRangeException | Exception thrown when an illegal index was requested. |
Table 3.2. Runtime exceptions
| Name | Description |
|---|---|
ConfigurationException | Exception thrown when a configuration requirement is not met. |
DatabaseException | Exception thrown when there is a database error. |
EndOfFileException | Exception thrown when an end of file is reached. |
NotPermittedException | Exception thrown when permission requirements are not met. |
OutOfBoundsException | Exception thrown when an illegal index was requested. |
OverflowException | Exception thrown to indicate arithmetic/buffer overflow. |
RangeException | Exception thrown to indicate range errors during program execution. |
UnderflowException | Exception thrown to indicate arithmetic/buffer underflow. |
UnexpectedValueException | Exception thrown to indicate an unexpected value. |
By default, Web:Extend will catch all exceptions and print an error page.
The framework also transforms any triggered error in an ErrorException which are then catchable like any other exception.
The error page contains generic information about the error and a few instructions to help the user of the application.
In DEBUG mode, the page will also contains a detailed report on the error, including a trace, if available.
You can customize the error page and set up your own instead of the generic one.
To do this, simply call weeException::setErrorPage with the path to the error page file.
This file will then get included, which means it can be a PHP script or just a simple HTML file.
It will also be provided with $aDebug, an array containing debugging informations.
You are free to use it or to ignore it.
Here is an example calling this method:
<?php
weeException::setErrorPage(ROOT_PATH . 'app/tpl/error_page.tpl');
The $aDebug array contains the following values:
type: either 'error' or 'exception'
name: name of the error/exception
message: description of the problem
trace: complete trace leading to the uncatched exception
file: the file where the error occurred
line: the line where the error occurred
number: only for errors; the error's number
You can take a look at the default error page located at trunk/res/wee/error.htm for a detailed example using this array.
Avoid throwing exceptions directly using the throw keyword.
If you make a typo in the exception's name, it will result in a fatal error.
The framework defines the burn function for throwing exceptions.
It takes two parameters: the exception name and the error message. If the exception doesn't exist, a DoubleFaultException is thrown instead.
If you really need a script to finish properly, catching Exception directly will ensure there is no problem, even if you made a typo.
A few examples:
<?php // Instead of this... throw new Exception('Oops!'); // Do this! burn('Exception', 'Oops!'); // You can also use it this way: $r = fopen('/path/to/file', 'r') or burn('FileNotFoundException', 'The file /path/to/file does not exist.');
As explained before, when an error is triggered, the default error handler throws an ErrorException with the same informations as the triggered error. The default error handler totally ignores the error level set through error_reporting so every catchable error is caught by it.
The following snippet demonstrates how to catch PHP errors.
<?php
try {
$a = array();
echo $a[42]; // triggers a notice
} catch (ErrorException $e) {
echo $e; // echoes "Undefined offset: 42"
}
The shut-up operator @ should be used only in the following two conditions:
If it makes more sense to throw a specific exception instead of ErrorException.
If the target code must never fail. This condition should be very rare.
It is a really bad practice to use it when combined with an instruction that might include or parse a PHP file, as it would mask the error and display a blank page.
The following rules define how the developer can choose between the various exceptions:
If under normal use of the class the script should be terminated upon encountering a PHP error then use ErrorException.
If the normal use of the class may require the developer to catch an exception upon an error in a method and continue normally
then use a normal exception instead of ErrorException. Example: FileNotFoundException, BadXMLException.
If the normal use of the class require the developer to catch exceptions to determine if an action was successful, then use a custom exception
for the class/module. Example: FormValidationException, AuthenticationException, RouteNotFoundException.
Only for the last 2 cases the docComment should inform the developer of the exceptions that can be thrown by the function or method.
There is no need to check for invalid arguments unless not doing so could result in an illegal state.
For example, the checks done in weeAuthDbTable::__construct are important
because without them invalid arguments would not prevent the construction of the object
and yet the authenticate and authenticateHash methods would always fail,
thus rendering the object useless.