LoginSignup
3
5

More than 5 years have passed since last update.

Laravelでパスごとにエラービューを出し分ける

Last updated at Posted at 2018-03-16

Laravelではexceptionのハンドリングを app/Exceptions/Handler.phpで指定できます。
このクラスの実装は大半が親クラスのIlluminate\Foundation\Exceptions\Handlerにあるので、
参考にしながらメソッドをオーバーライドしていきます。

app/Exception/Hander.php
    /**
     * Prepare a response for the given exception.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception $e
     * @return \Symfony\Component\HttpFoundation\Response
     */
    protected function prepareResponse($request, Exception $e)
    {
        if (! $this->isHttpException($e) && config('app.debug')) {
            return $this->toIlluminateResponse(
                $this->convertExceptionToResponse($e), $e
            );
        }

        if (! $this->isHttpException($e)) {
            $e = new HttpException(500, $e->getMessage());
        }

        // パスごとにエラーのviewを分岐する
        return $this->toIlluminateResponse(
            $this->customRenderHttpException($request, $e), $e // ここがparentのものと差し替わっている
        );
    }

    /**
     * parentのrenderHttpExceptionを改変してrequestパスごとに分岐するようにしたもの
     * @param Request $request
     * @param \Symfony\Component\HttpKernel\Exception\HttpException  $e
     * @return \Symfony\Component\HttpFoundation\Response
     */
    private function customRenderHttpException(Request $request, HttpException $e)
    {
        $status = $e->getStatusCode();

        $paths = collect(config('view.paths'));

        view()->replaceNamespace('errors', $paths->map(function ($path) use ($request) {
            return $request->is('admin/*') ? "{$path}/admin/errors" : "{$path}/service/errors"; // viewを分岐
        })->push(__DIR__ . '/views')->all());

        if (view()->exists($view = "errors::{$status}")) {
            return response()->view($view, ['exception' => $e], $status, $e->getHeaders());
        }

        return $this->convertExceptionToResponse($e);
    }

今回はadmin/以下にアクセスが来たときは/views/admin/errorsにそれ以外のときは/views/service/errorsに振り分けます。

親クラスにconvertExceptionToResponseというメソッドがあってそこだけ書き換えられればよかったのですが、パスで分岐するためには\Illuminate\Http\Requestが引数に必要で、それが無かったので、prepareResponseメソッドから書き換えています。

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5