runtime-handling-errors.md 9.92 KB
Newer Older
1 2
エラー処理
==========
3

4 5
Yii は、エラー処理を従来よりはるかに快適な経験にしてくれる、内臓の [[yii\web\ErrorHandler|エラーハンドラ]]
を持っています。具体的には、Yii のエラーハンドラはエラー処理を向上させるために、次のことを行います。
6

7 8 9 10
* 致命的でない全ての PHP エラー (警告や通知) は捕捉可能な例外に変換されます。
* 例外と致命的な PHP エラーは、デバッグモードでは、詳細なコールスタック情報とソースコード行とともに表示されます。
* エラーを表示するために専用の [コントローラアクション](structure-actions.md) を使うことがサポートされています。
* さまざまなエラーレスポンス形式をサポートしています。
11

12 13
[[yii\web\ErrorHandler|エラーハンドラ]] は既定で有効になっています。アプリケーションの [エントリスクリプト](structure-entry-scripts.md)
において、定数 `YII_ENABLE_ERROR_HANDLER` を false と定義することによって、これを無効にすることが出来ます。
14 15


16
## エラーハンドラを使用する <a name="using-error-handler"></a>
17

18 19
[[yii\web\ErrorHandler|エラーハンドラ]] は `errorHandler` という名前の [アプリケーションコンポーネント](structure-application-components.md) です。
次のように、アプリケーションのコンフィギュレーションでこれをカスタマイズすることが出来ます。
20 21 22 23 24 25 26 27 28 29 30

```php
return [
    'components' => [
        'errorHandler' => [
            'maxSourceLines' => 20,
        ],
    ],
];
```

31
上記のコンフィギュレーションによって、例外ページで表示されるソースコードの行数は最大で 20 までとなります。
32

33 34
既に述べたように、エラーハンドラは致命的でない全ての PHP エラーを捕捉可能な例外に変換します。
これは、次のようなコードを使って PHP エラーを処理することが出来るということを意味します。
35 36 37 38 39 40 41 42

```php
use Yii;
use yii\base\ErrorException;

try {
    10/0;
} catch (ErrorException $e) {
43
    Yii::warning("0 による除算。");
44 45
}

46
// 実行を継続 ...
47 48
```

49 50 51
ユーザに対して、リクエストが無効であったり予期しないものであったりすることを知らせるエラーページを表示したい場合は、
単に [[yii\web\NotFoundHttpException]] のような [[yii\web\HttpException|HTTP 例外]] を投げるだけで済ませることが出来ます。
エラーハンドラがレスポンスの HTTP ステータスコードを正しく設定し、適切なエラービューを使ってエラーメッセージを表示してくれます。
52 53 54 55 56 57 58 59

```php
use yii\web\NotFoundHttpException;

throw new NotFoundHttpException();
```


60
## エラー表示をカスタマイズする <a name="customizing-error-display"></a>
61

62 63 64 65
[[yii\web\ErrorHandler|エラーハンドラ]] は、定数 `YII_DEBUG` の値に従って、エラー表示を調整します。
`YII_DEBUG` が true である (デバッグモードである) 場合は、エラーハンドラは、デバッグがより容易になるように、
詳細なコールスタック情報とソースコード行とともに例外を表示します。そして、`YII_DEBUG` が false のときは、
アプリケーションに関する公開できない情報を開示することを防ぐために、エラーメッセージだけが表示されます。
66

67 68
> Info|情報: 例外が [[yii\base\UserException]] の子孫である場合は、`YII_DEBUG` の値の如何にかかわらず、コールスタックは表示されません。
これは、この種の例外はユーザの誤操作によって引き起こされるものであり、開発者は何も修正する必要がないと考えられるからです。
69

70
既定では、[[yii\web\ErrorHandler|エラーハンドラ]] は二つの [views](structure-views.md) を使ってエラーを表示します。
71

72 73 74
* `@yii/views/errorHandler/error.php`: エラーがコールスタック情報なしで表示されるべき場合に使用されます。
  `YII_DEBUG` が false の場合、これが表示される唯一のビューとなります。
* `@yii/views/errorHandler/exception.php`: エラーがコールスタック情報と共に表示されるべき場合に使用されます。
75

76 77
エラー表示をカスタマイズするために、エラーハンドラの [[yii\web\ErrorHandler::errorView|errorView]] および
[[yii\web\ErrorHandler::exceptionView|exceptionView]] プロパティを構成して、自分自身のビューを使用することが出来ます。
78 79


80
### エラーアクションを使う <a name="using-error-actions"></a>
81

82 83 84
エラー表示をカスタマイズするためのもっと良い方法は、専用のエラー [アクション](structure-controllers.md) を使うことです。
そうするためには、まず、`errorHandler` コンポーネントの [[yii\web\ErrorHandler::errorAction|errorAction]]
プロパティを次のように構成します。
85 86 87 88 89 90 91 92 93 94 95

```php
return [
    'components' => [
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
    ]
];
```

96 97 98
[[yii\web\ErrorHandler::errorAction|errorAction]] プロパティは、アクションへの [ルート](structure-controllers.md#routes) を値として取ります。
上記のコンフィギュレーションは、エラーをコールスタック情報なしで表示する必要がある場合は、`site/error`
アクションが実行されるべきであることを記述しています。
99

100
`site/error` アクションは次のようにして作成することが出来ます。
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120

```php
namespace app\controllers;

use Yii;
use yii\web\Controller;

class SiteController extends Controller
{
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }
}
```

121
上記のコードは [[yii\web\ErrorAction]] クラスを使って `error` アクションを定義しています。[[yii\web\ErrorAction]] クラスは `error` という名前のビューを使ってエラーをレンダリングします。
122

123
[[yii\web\ErrorAction]] を使う以外に、次のようにアクションメソッドを使って `error` アクションを定義することも出来ます。
124 125 126 127 128 129 130 131 132 133 134

```php
public function actionError()
{
    $exception = Yii::$app->errorHandler->exception;
    if ($exception !== null) {
        return $this->render('error', ['exception' => $exception]);
    }
}
```

135 136
次に `views/site/error.php` に配置されるビューファイルを作成しなければなりません。エラーアクションが [[yii\web\ErrorAction]]
として定義されている場合は、このビューファイルの中で次の変数にアクセスすることが出来ます。
137

138 139 140 141
* `name`: エラーの名前。
* `message`: エラーメッセージ。
* `exception`: 例外オブジェクト。これを通じて、更に有用な情報、例えば、HTTP ステータスコード、
エラーコード、エラーコールスタックなどにアクセス出来ます。
142

143 144 145
> Info|情報: あなたが [ベーシックアプリケーションテンプレート](start-installation.md) または
[アドバンストアプリケーションテンプレート](tutorial-advanced-app.md) を使っている場合は、
エラーアクションとエラービューは、既にあなたのために定義されています。
146 147


148
### エラーのレスポンス形式をカスタマイズする <a name="error-format"></a>
149

150 151 152 153 154
エラーハンドラは、[レスポンス](runtime-responses.md) の形式の設定に従ってエラーを表示します。
[[yii\web\Response::format|レスポンス形式]] が `html` である場合は、直前の項で説明したように、
エラービューまたは例外ビューを使ってエラーを表示します。その他のレスポンス形式の場合は、
エラーハンドラは例外の配列表現を [[yii\web\Response::data]] プロパティに代入し、次に `data` プロパティがレスポンス形式に応じて様々な形式に変換されます。
例えば、レスポンス形式が `json` である場合は、次のようなレスポンスになります。
155 156 157 158 159 160 161 162 163 164

```
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

{
    "name": "Not Found Exception",
165
    "message": "リクエストされたリソースは見つかりませんでした。",
166 167 168 169 170
    "code": 0,
    "status": 404
}
```

171 172
エラーのレスポンス形式をカスタマイズするために、アプリケーションのコンフィギュレーションの中で、
`response` コンポーネントの `beforeSend` イベントに反応するハンドラを構成することが出来ます。
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

```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;
                }
            },
        ],
    ],
];
```

195
上記のコードは、エラーのレスポンスを以下のようにフォーマットし直すものです。
196 197 198 199 200 201 202 203 204 205 206 207

```
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",
208
        "message": "リクエストされたリソースは見つかりませんでした。",
209 210 211 212 213
        "code": 0,
        "status": 404
    }
}
```