Laravel は、デフォルトで例外をキャッチして、サーバーエラーの表示をしてくれる。
この処理を行っているのは、 App\Exceptions\Handler
である。
このクラスは Illuminate\Foundation\Exceptions\Handler
を継承して作られており、メインの処理を行っているのは Illuminate\Foundation\Exceptions\Handler
の方である。
Illuminate\Foundation\Exceptions\Handler
を継承して拡張することで、様々なエラーレスポンスを返すことができます。
なお、デフォルトだと、 bootstrap/app.php
において
<?php $app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class );
という設定があります。
Handler の処理を見ていく
Illuminate\Foundation\Exceptions\Handler::render
が、実際にエラーメッセージを表示するロジックである。
<?php public function render($request, Throwable $e) { if (method_exists($e, 'render') && $response = $e->render($request)) { return Router::toResponse($request, $response); } elseif ($e instanceof Responsable) { return $e->toResponse($request); } $e = $this->prepareException($e); if ($e instanceof HttpResponseException) { return $e->getResponse(); } elseif ($e instanceof AuthenticationException) { return $this->unauthenticated($request, $e); } elseif ($e instanceof ValidationException) { return $this->convertValidationExceptionToResponse($e, $request); } return $request->expectsJson() ? $this->prepareJsonResponse($request, $e) : $this->prepareResponse($request, $e); }
最初の部分
<?php if (method_exists($e, 'render') && $response = $e->render($request)) { return Router::toResponse($request, $response); } elseif ($e instanceof Responsable) { return $e->toResponse($request); }
もし、投げられた例外に render メソッドがあったり、 Responsable インタフェースが実装されていたら、そのメソッドを読んで結果を表示します。
次の部分
<?php $e = $this->prepareException($e); if ($e instanceof HttpResponseException) { return $e->getResponse(); } elseif ($e instanceof AuthenticationException) { return $this->unauthenticated($request, $e); } elseif ($e instanceof ValidationException) { return $this->convertValidationExceptionToResponse($e, $request); }
この部分は、一部例外については、それに対応したエラーを表示する対応になります。
最後の部分
<?php return $request->expectsJson() ? $this->prepareJsonResponse($request, $e) : $this->prepareResponse($request, $e);
これは、これまで処理してきた例外以外の例外の場合に適用される処理です。
エラーメッセージを、 Json または HTML で表示します。
$request->expectsJson()
$request->expectsJson()
が true の場合、エラーレスポンスは Json 形式で返されることになります。
例えば、 Accept ヘッダーで、レスポンス形式 application/json
などを要求している場合は、レスポンスが自動的に Json に変換されます。
他にも、ヘッダに X-Requested-With: XMLHttpRequest
が指定されていると、ajax によるリクエストとみなされ、 Json のレスポンスを返すようになっています。
ヘッダに X-PJAX が指定されていて、 Accept ヘッダが指定されていない場合、pjax リクエストとみなされて、Json のレスポンスを返すようになっています。