mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-24 10:39:03 +08:00
finished error handling guide [skip ci]
This commit is contained in:
@@ -49,7 +49,6 @@ Sometimes you may want to customize the default error response format. For examp
|
||||
using different HTTP statuses to indicate different errors, you would like to always use 200 as HTTP status
|
||||
and enclose the actual HTTP status code as part of the JSON structure in the response, like shown in the following,
|
||||
|
||||
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Date: Sun, 02 Mar 2014 05:31:43 GMT
|
||||
|
||||
@@ -1,96 +1,217 @@
|
||||
Error Handling
|
||||
==============
|
||||
Handling Errors
|
||||
===============
|
||||
|
||||
> Note: This section is under development.
|
||||
Yii includes a built-in [[yii\web\ErrorHandler|error handler]] which makes error handling a much more pleasant
|
||||
experience than before. In particular, the Yii error handler does the followings to improve error handling:
|
||||
|
||||
Error handling in Yii is different than handling errors in plain PHP. First of all, Yii will convert all non-fatal errors
|
||||
to *exceptions*:
|
||||
* All non-fatal PHP errors (e.g. warnings, notices) are converted into catchable exceptions.
|
||||
* Exceptions and fatal PHP errors are displayed with detailed call stack information and source code lines
|
||||
in debug mode.
|
||||
* Support using a dedicated [controller action](structure-actions.md) to display errors.
|
||||
* Support different error response formats.
|
||||
|
||||
The [[yii\web\ErrorHandler|error handler]] is enabled by default. You may disable it by defining the constant
|
||||
`YII_ENABLE_ERROR_HANDLER` to be false in the [entry script](structure-entry-scripts.md) of your application.
|
||||
|
||||
|
||||
## Using Error Handler <a name="using-error-handler"></a>
|
||||
|
||||
The [[yii\web\ErrorHandler|error handler]] is registered as an application component named `errorHandler`.
|
||||
You may configure it in the application configuration like the following:
|
||||
|
||||
```php
|
||||
return [
|
||||
'components' => [
|
||||
'errorHandler' => [
|
||||
'maxSourceLines' => 20,
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
With the above configuration, the number of source code lines to be displayed in exception pages will be up to 20.
|
||||
|
||||
As aforementioned, the error handler turns all non-fatal PHP errors into catchable exceptions. This means you can
|
||||
use the following code to deal with PHP errors:
|
||||
|
||||
```php
|
||||
use yii\base\ErrorException;
|
||||
use Yii;
|
||||
use yii\base\ErrorException;
|
||||
|
||||
try {
|
||||
10/0;
|
||||
} catch (ErrorException $e) {
|
||||
Yii::warning("Tried dividing by zero.");
|
||||
Yii::warning("Division by zero.");
|
||||
}
|
||||
|
||||
// execution may continue
|
||||
// execution continues...
|
||||
```
|
||||
|
||||
As demonstrated above you may handle errors using `try`-`catch`.
|
||||
|
||||
Second, even fatal errors in Yii are rendered in a nice way. This means that in debugging mode, you can trace the causes
|
||||
of fatal errors in order to more quickly identify the cause of the problem.
|
||||
|
||||
|
||||
Rendering errors in a dedicated controller action
|
||||
-------------------------------------------------
|
||||
|
||||
The default Yii error page is great when developing a site, and is acceptable for production sites if `YII_DEBUG`
|
||||
is turned off in your bootstrap `index.php` file. But you may want to customize the default error page to make it
|
||||
more suitable for your project.
|
||||
|
||||
The easiest way to create a custom error page it is to use a dedicated controller action for error rendering. First,
|
||||
you'll need to configure the `errorHandler` component in the application's configuration:
|
||||
If you want to show an error page telling the user that his request is invalid or unexpected, you may simply
|
||||
throw an [[yii\web\HttpException|HTTP exception]], such as [[yii\web\NotFoundHttpException]]. The error handler
|
||||
will correctly set the HTTP status code of the response and use an appropriate error view to display the error
|
||||
message.
|
||||
|
||||
```php
|
||||
// ...
|
||||
'components' => [
|
||||
// ...
|
||||
'errorHandler' => [
|
||||
'errorAction' => 'site/error',
|
||||
],
|
||||
]
|
||||
use yii\web\NotFoundHttpException;
|
||||
|
||||
throw new NotFoundHttpException();
|
||||
```
|
||||
|
||||
With that configuration in place, whenever an error occurs, Yii will execute the `error`-action of the `site`-controller.
|
||||
That action should look for an exception and, if present, render the proper view file, passing along the exception:
|
||||
|
||||
## Customizing Error Display <a name="customizing-error-display"></a>
|
||||
|
||||
The [[yii\web\ErrorHandler|error handler]] adjusts error display according to the value of the constant `YII_DEBUG`.
|
||||
When `YII_DEBUG` is true (meaning in debug mode), the error handler will display exceptions with detailed call
|
||||
stack information and source code lines to help easier debugging. And when `YII_DEBUG` is false, only the error
|
||||
message will be displayed to prevent from revealing sensitive information of the application.
|
||||
|
||||
> Info: If an exception is a descendant of [[yii\base\UserException]], no call stack will be displayed regardless
|
||||
the value of `YII_DEBUG`. This is because such exceptions are considered to be caused by user mistakes and the
|
||||
developers do not need to fix anything.
|
||||
|
||||
By default, the [[yii\web\ErrorHandler|error handler]] displays errors using two [views](structure-views.md):
|
||||
|
||||
* `@yii/views/errorHandler/error.php`: used when errors should be displayed WITHOUT call stack information.
|
||||
When `YII_DEBUG` is false, this is the only error view to be displayed.
|
||||
* `@yii/views/errorHandler/exception.php`: used when errors should be displayed WITH call stack information.
|
||||
|
||||
You can configure the [[yii\web\ErrorHandler::errorView|errorView]] and [[yii\web\ErrorHandler::exceptionView|exceptionView]]
|
||||
properties of the error handler to use your own views to customize the error display.
|
||||
|
||||
|
||||
### Using Error Actions <a name="using-error-actions"></a>
|
||||
|
||||
A better way of customizing the error display is to use dedicated error [actions](structure-controllers.md).
|
||||
To do so, first configure the [[yii\web\ErrorHandler::errorAction|errorAction]] property of the `errorHandler`
|
||||
component like the following:
|
||||
|
||||
```php
|
||||
return [
|
||||
'components' => [
|
||||
'errorHandler' => [
|
||||
'errorAction' => 'site/error',
|
||||
],
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
The [[yii\web\ErrorHandler::errorAction|errorAction]] property takes a [route](structure-controllers.md#routes)
|
||||
to an action. The above configuration states that when an error needs to be displayed without call stack information,
|
||||
the `site/error` action should be executed.
|
||||
|
||||
You can create the `site/error` action as follows,
|
||||
|
||||
```php
|
||||
namespace app\controllers;
|
||||
|
||||
use Yii;
|
||||
use yii\web\Controller;
|
||||
|
||||
class SiteController extends Controller
|
||||
{
|
||||
public function actions()
|
||||
{
|
||||
return [
|
||||
'error' => [
|
||||
'class' => 'yii\web\ErrorAction',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The above code defines the `error` action using the [[yii\web\ErrorAction]] class which renders an error
|
||||
using a view named `error`.
|
||||
|
||||
Besides using [[yii\web\ErrorAction]], you may also define the `error` action using an action method like the following,
|
||||
|
||||
```php
|
||||
public function actionError()
|
||||
{
|
||||
$exception = \Yii::$app->errorHandler->exception;
|
||||
$exception = Yii::$app->errorHandler->exception;
|
||||
if ($exception !== null) {
|
||||
return $this->render('error', ['exception' => $exception]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Next, you would create the `views/site/error.php` file, which would make use of the exception. The exception object has
|
||||
the following properties:
|
||||
You should now create a view file located at `views/site/error.php`. In this view file, you can access
|
||||
the following variables if the error action is defined as [[yii\web\ErrorAction]]:
|
||||
|
||||
- `statusCode`: the HTTP status code (e.g. 403, 500). Available for [[yii\web\HttpException|HTTP exceptions]] only.
|
||||
- `code`: the code of the exception.
|
||||
- `message`: the error message.
|
||||
- `file`: the name of the PHP script file where the error occurs.
|
||||
- `line`: the line number of the code where the error occurs.
|
||||
- `trace`: the call stack of the error.
|
||||
* `name`: the name of the error;
|
||||
* `message`: the error message;
|
||||
* `exception`: the exception object through which you can more useful information, such as HTTP status code,
|
||||
error code, error call stack, etc.
|
||||
|
||||
> Info: If you are using the [basic application template](start-installation.md) or the [advanced application template](tutorial-advanced-app.md),
|
||||
the error action and the error view are already defined for you.
|
||||
|
||||
|
||||
Rendering errors without a dedicated controller action
|
||||
------------------------------------------------------
|
||||
### Customizing Error Response Format <a name="error-format"></a>
|
||||
|
||||
Instead of creating a dedicated action within the Site controller, you could just indicate to Yii what class should
|
||||
be used to handle errors:
|
||||
The error handler displays errors according to the format setting of the [response](runtime-responses.md).
|
||||
If the the [[yii\web\Response::format|response format]] is `html`, it will use the error or exception view
|
||||
to display errors, as described in the last subsection. For other response formats, the error handler will
|
||||
assign the array representation of the exception to the [[yii\web\Response::data]] property which will then
|
||||
be converted to different formats accordingly. For example, if the response format is `json`, you may see
|
||||
the following response:
|
||||
|
||||
```
|
||||
HTTP/1.1 404 Not Found
|
||||
Date: Sun, 02 Mar 2014 05:31:43 GMT
|
||||
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
|
||||
Transfer-Encoding: chunked
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
```php
|
||||
public function actions()
|
||||
{
|
||||
return [
|
||||
'error' => [
|
||||
'class' => 'yii\web\ErrorAction',
|
||||
],
|
||||
];
|
||||
"name": "Not Found Exception",
|
||||
"message": "The requested resource was not found.",
|
||||
"code": 0,
|
||||
"status": 404
|
||||
}
|
||||
```
|
||||
|
||||
After associating the class with the error as in the above, define the `views/site/error.php` file, which will
|
||||
automatically be used. The view will be passed three variables:
|
||||
You may customize the error response format by responding to the `beforeSend` event of the `response` component
|
||||
in the application configuration:
|
||||
|
||||
- `$name`: the error name
|
||||
- `$message`: the error message
|
||||
- `$exception`: the exception being handled
|
||||
```php
|
||||
return [
|
||||
// ...
|
||||
'components' => [
|
||||
'response' => [
|
||||
'class' => 'yii\web\Response',
|
||||
'on beforeSend' => function ($event) {
|
||||
$response = $event->sender;
|
||||
if ($response->data !== null) {
|
||||
$response->data = [
|
||||
'success' => $response->isSuccessful,
|
||||
'data' => $response->data,
|
||||
];
|
||||
$response->statusCode = 200;
|
||||
}
|
||||
},
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
The `$exception` object will have the same properties as outlined above.
|
||||
The above code will reformat the error response like the following:
|
||||
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Date: Sun, 02 Mar 2014 05:31:43 GMT
|
||||
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
|
||||
Transfer-Encoding: chunked
|
||||
Content-Type: application/json; charset=UTF-8
|
||||
|
||||
{
|
||||
"success": false,
|
||||
"data": {
|
||||
"name": "Not Found Exception",
|
||||
"message": "The requested resource was not found.",
|
||||
"code": 0,
|
||||
"status": 404
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -162,6 +162,10 @@ under the categories whose names match either `yii\db\*` or `yii\web\HttpExcepti
|
||||
]
|
||||
```
|
||||
|
||||
> Info: When an HTTP exception is caught by the [error handler](runtime-handling-errors.md), an error message
|
||||
will be logged with the category name in the format of `yii\web\HttpException:ErrorCode`. For example,
|
||||
the [[yii\web\NotFoundHttpException]] will cause an error message of category `yii\web\HttpException:404`.
|
||||
|
||||
|
||||
### Message Formatting <a name="message-formatting"></a>
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@ runtime-requests.md | Yes
|
||||
runtime-responses.md | Yes
|
||||
runtime-sessions-cookies.md | Yes
|
||||
runtime-url-handling.md |
|
||||
runtime-handling-errors.md |
|
||||
runtime-logging.md |
|
||||
runtime-handling-errors.md | Yes
|
||||
runtime-logging.md | Yes
|
||||
concept-components.md | Yes
|
||||
concept-properties.md | Yes
|
||||
concept-events.md | Yes
|
||||
|
||||
Reference in New Issue
Block a user