はじめに
Laravel5.5で任意のエラー画面を出したくて奮闘した話。最初は下記の要件を満たしたいだけだった。
abort
関数でエラーコードに応じた任意の画面を出力する- ぬるぽや未定義変数を参照するなど想定外のエラーの際に任意の画面を出力する
これをネットの記事を参考にし、Laravelで例外処理をハンドリングしてるであろうapp/Exceptions/Handler.php
のrender
メソッドを以下のように編集した。
public function render($request, Exception $exception) { + if ($this->isHttpException($exception)) { + if ($exception->getStatusCode() == 400) { + return response()->view('errors.400', [], 400); + } + } else { + return response()->view('errors.500', [], 500); + } + - return parent::render($request, $exception); }
とりあえずこれでabort
関数で任意のページを表示してくれるし、想定外のエラーが起きた際にも500システムエラーページを表示してくれるようになった。やったぜ!と喜んでいるのもつかの間、問題が発生する。
問題発生!
入力されたデータに対する自動バリデーションが思うように動作しなくなった。なんでだろうと思い編集前のapp/Exceptions/Handler.php
のrender
メソッドを見直すと、
return parent::render($request, $exception);
こいつが目に入った。中を覗いてみると以下のようになっていた。
public function render($request, Exception $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); }
ValidationException
の文字が見える。なるほど、parent::render
メソッドでバリデーションとっていたのか。今回はparent::render
メソッドを消していた、道理でバリデートされないわけだ。
無事解決!
app/Exceptions/Handler.php
のrender
メソッドを再び修正する。
public function render($request, Exception $exception) { + if ($this->isHttpException($exception)) { + if ($exception->getStatusCode() == 400) { + return response()->view('errors.400', [], 400); + } + } + + if ($exception instanceof ErrorException) { + return response()->view('errors.500', [], 500); + } + return parent::render($request, $exception); }
上記のコードの通り$exception
がHttpException
のときは任意のエラーページを表示し、想定していないエラーについてはErrorExceptoin
で補足してシステムエラーページを表示する。さらにHttpException
とErrorException
以外の何かしらの例外やエラーについてはparent::render
メソッドで処理をするようにし、自動バリデーションなど適切に処理が行われるようにした。
おわりに
既存のコードに変更を加える前にしっかりと周辺のコードを読み込まないとアカンですね。気をつけよう。