カスタム例外ハンドラーを使用したLaravel404ページの作成
序章
前例のないイベントまたはエラーが発生すると、PHP例外がスローされます。 経験則として、例外はifステートメントなどのアプリケーションロジックを制御するために使用されるべきではなく、 Exception
クラス。
前例のないことであるため、アプリケーションの任意の時点または時点で例外がスローされる可能性があります。
Laravelは、Laravelアプリケーションでスローされたすべての例外をチェックし、関連する応答を提供する便利な例外ハンドラークラスを提供します。 これは、Laravelで使用されるすべての例外がExceptionクラスを拡張するという事実によって可能になります。
すべての例外を単一のクラスでキャッチすることの主な利点の1つは、例外に応じて異なる応答メッセージを返すカスタム例外ハンドラーを作成できることです。
このチュートリアルでは、Laravel 5.2でカスタム例外ハンドラーを作成する方法と、例外に応じて404ページを返す方法を見ていきます。
使い方
Laravel 5.2では、カスタムとデフォルトの両方のすべてのエラーと例外は、 Handler
のクラス app/Exceptions/Handler.php
2つの方法の助けを借りて。
report()
reportメソッドを使用すると、発生した例外をログに記録したり、bugsnagやsentryなどのエラーログエンジンに解析したりできます。これらについてはこのチュートリアルでは詳しく説明しません。
render()
renderメソッドは、例外によって発生したエラーメッセージで応答します。 例外からHTTP応答を生成し、ブラウザに送り返します。
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
return parent::render($request, $e);
}
ただし、独自のカスタム例外ハンドラーを使用して、デフォルトのエラー処理をオーバーライドできます。
/**
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($e instanceof CustomException) {
return response()->view('errors.custom', [], 500);
}
return parent::render($request, $e);
}
内部的には、Laravelは独自の処理チェックを実行して、例外に対する可能な限り最良の応答を決定します。 親クラスを見てみましょう(Illuminate\Foundation\Exceptions\Handler
)、renderメソッドは、スローされた例外に応じて異なる応答を生成します。
/**
* Render an exception into a response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Symfony\Component\HttpFoundation\Response
*/
public function render($request, Exception $e)
{
if ($e instanceof HttpResponseException) {
return $e->getResponse();
} elseif ($e instanceof ModelNotFoundException) {
$e = new NotFoundHttpException($e->getMessage(), $e);
} elseif ($e instanceof AuthenticationException) {
return $this->unauthenticated($request, $e);
} elseif ($e instanceof AuthorizationException) {
$e = new HttpException(403, $e->getMessage());
} elseif ($e instanceof ValidationException && $e->getResponse()) {
return $e->getResponse();
}
if ($this->isHttpException($e)) {
return $this->toIlluminateResponse($this->renderHttpException($e), $e);
} else {
return $this->toIlluminateResponse($this->convertExceptionToResponse($e), $e);
}
}
LaravelのEloquent例外をスローする
このセクションでは、意図的に例外を発生させて、組み込みのLaravelエラーを作成します。
これを行うには、を使用してモデルから存在しないレコードをフェッチしようとします firstOrFail()
雄弁な方法。
先に進み、簡単なSQLiteデータベースをセットアップします。 幸いなことに、Laravelには User
モデルと対応するユーザーテーブル。 次のようにするだけです。
- 新しいLaravelプロジェクトを作成します。
- 更新する
.env
DB_CONNECTIONがsqliteであり、唯一のデータベースパラメータであるファイル。 - データベースディレクトリにdatabase.sqliteファイルを作成します。 これは、で構成されているデフォルトのSQLiteデータベースです。
config/database.php
- 走る
php artisan migrate
Laravelプロジェクトのルート上。 これにより、データベースにユーザーテーブルが設定されます。
次に、ルートとコントローラーを追加して、usersテーブルの最初のユーザーを取得します。このユーザーはたまたま存在しません。
app / Http / routers.php
Route::get('/user', [
'uses' => 'SampleController@findUser',
'as' => 'user'
]);
App / Http / Controllers / SampleController.php
/**
* Return the first user in the users table
*
* @return Array User details
*/
public function findUser()
{
$user = User::firstOrFail();
return $user->toArray();
}
これをブラウザで実行すると、 ModelNotFoundException
エラー応答。
カスタムハンドラーを使用して例外をキャッチする
ModelNotFoundException
この例外を除いて、独自のエラーメッセージを返すカスタムハンドラーを追加できるようになりました。
変更します render
の方法 app/Exceptions/Handler.php
例外が次のいずれかである場合、ajaxリクエストのJSONレスポンス、または通常のリクエストのビューを返す ModelNotFoundException
また NotFoundHttpException
.
どちらでもない場合は、Laravelに例外を処理させます。
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
//check if exception is an instance of ModelNotFoundException.
if ($e instanceof ModelNotFoundException) {
// ajax 404 json feedback
if ($request->ajax()) {
return response()->json(['error' => 'Not Found'], 404);
}
// normal 404 view page feedback
return response()->view('errors.missing', [], 404);
}
return parent::render($request, $e);
}
追加する 404.blade.php
resources / view / errors にファイルして、ユーザーのフィードバックを含めます。
<!DOCTYPE html>
<html>
<head>
<title>User not found.</title>
</head>
<body>
<p>You broke the balance of the internet</p>
</body>
</html>
ここでページを更新すると、ビューに404ステータスコードを含む次のメッセージが表示されます。
NotFoundHttpException
ユーザーが/foo / bar / randomstr1ng などの未定義のルートにアクセスすると、 NotFoundHttpException
Symfonyパッケージの一部として提供される例外がスローされます。
この例外を処理するために、2番目の条件を render
以前に変更したメソッドで、 resources / view / errors /missing.blade.phpからメッセージを返します
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
//check if exception is an instance of ModelNotFoundException.
//or NotFoundHttpException
if ($e instanceof ModelNotFoundException or $e instanceof NotFoundHttpException) {
// ajax 404 json feedback
if ($request->ajax()) {
return response()->json(['error' => 'Not Found'], 404);
}
// normal 404 view page feedback
return response()->view('errors.missing', [], 404);
}
return parent::render($request, $e);
}
Laravelの中止方法を利用する
前のセクションで行ったように、Laravel 5.2では、スローされた例外に基づいてカスタムエラーページを簡単に作成できます。
を呼び出すことで、404エラーページの応答を生成することもできます。 abort
オプションの応答メッセージを受け取るメソッド。
abort(404, 'The resource you are looking for could not be found');
これにより、対応するものがチェックされます resources/view/errors/404.blade.php
404ステータスコードを含むHTTP応答をブラウザに返します。 同じことが401および500エラーステータスコードにも当てはまります。
結論
アプリケーションの環境に応じて、さまざまなレベルのエラーの詳細を表示したい場合があります。 あなたは設定することができます APP_DEBUG
の値 config/app.php
あなたの中でそれを変更することによって真または偽のいずれかに .env
ファイル。
ほとんどの場合、本番環境のユーザーに詳細なエラーメッセージを表示させたくない場合があります。 したがって、設定することをお勧めします APP_DEBUG
実稼働環境では、値をfalseに設定します。