序章

前例のないイベントまたはエラーが発生すると、PHP例外がスローされます。 経験則として、例外はifステートメントなどのアプリケーションロジックを制御するために使用されるべきではなく、Exceptionクラスのサブクラスである必要があります。

前例のないため、アプリケーションの任意の時点または時点で例外がスローされる可能性があります。

Laravelは、Laravelアプリケーションでスローされたすべての例外をチェックし、関連する応答を提供する便利な例外ハンドラークラスを提供します。 これは、Laravelで使用されるすべての例外がExceptionクラスを拡張するという事実によって可能になります。

すべての例外を単一のクラスでキャッチすることの主な利点の1つは、例外に応じて異なる応答メッセージを返すカスタム例外ハンドラーを作成できることです。

このチュートリアルでは、Laravel 5.2でカスタム例外ハンドラーを作成する方法と、例外に応じて404ページを返す方法を見ていきます。

使い方

Laravel 5.2では、カスタムとデフォルトの両方のすべてのエラーと例外は、2つのメソッドを使用してapp/Exceptions/Handler.phpHandlerクラスによって処理されます。

  • report()

reportメソッドを使用すると、発生した例外をログに記録したり、bugsnagsentryなどのエラーログエンジンに解析したりできます。これらについてはこのチュートリアルでは詳しく説明しません。

  • 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() Eloquentメソッドを使用して、モデルから存在しないレコードをフェッチしようとします。

先に進み、簡単なSQLiteデータベースをセットアップします。 幸い、LaravelにはUserモデルと対応するユーザーテーブルが付属しています。 次のようにするだけです。

  1. 新しいLaravelプロジェクトを作成します。
  2. .envファイルを更新して、DB_CONNECTIONsqliteおよび唯一のデータベースパラメーターにします。
  3. データベースディレクトリにdatabase.sqliteファイルを作成します。 これは、config/database.phpで構成されているデフォルトのSQLiteデータベースです。
  4. Laravelプロジェクトのルートでphp artisan migrateを実行します。 これにより、データベースにユーザーテーブルが設定されます。

次に、ルートとコントローラーを追加して、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エラー応答が返されます。

NotFoundHttpException

カスタムハンドラを使用して例外をキャッチする

ModelNotFoundException

この例外を除いて、独自のエラーメッセージを返すカスタムハンドラーを追加できるようになりました。

app/Exceptions/Handler.phprenderメソッドを変更して、例外が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);
    }

resources / view / errors404.blade.phpファイルを追加して、ユーザーからのフィードバックを含めます。

<!DOCTYPE html>
<html>
<head>
    <title>User not found.</title>
</head>
<body>
    <p>You broke the balance of the internet</p>
</body>
</html>

ここでページを更新すると、ビューに404ステータスコードを含む次のメッセージが表示されます。

Custom exception handling with 404 status code feedback

NotFoundHttpException

ユーザーが/foo / bar / randomstr1ng などの未定義のルートにアクセスすると、Symfonyパッケージの一部として提供されるNotFoundHttpException例外がスローされます。

この例外を処理するために、前に変更したrenderメソッドに2番目の条件を追加し、 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では、スローされた例外に基づいてカスタムエラーページを簡単に作成できます。

オプションの応答メッセージを受け取るabortメソッドを呼び出すことで、404エラーページ応答を簡単に生成することもできます。

abort(404, 'The resource you are looking for could not be found');

これにより、対応するresources/view/errors/404.blade.phpがチェックされ、404ステータスコードを含むHTTP応答がブラウザに返されます。 同じことが401および500エラーステータスコードにも当てはまります。

結論

アプリケーションの環境に応じて、さまざまなレベルのエラーの詳細を表示したい場合があります。 [X32X]