はじめに
CMSを作成していて、大部分の実装が終わったので、404ページの実装を行おうと思い
404になる部分に対して
App:abort('404');
で404にしようと思ったら、下記のメッセージがでた。
これがなかなか曲者で、アプリエラーログ、apacheのエラーログに有力なログが落ちず、
Log::error()でどこまで処理が通っているかを地道に調査をするしかなかった。
http://sugi511.hatenablog.com/entry/2014/08/11/Laravel4%E3%81%A7%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%9F%E6%99%82%E3%81%AB%E3%80%8CError_in_exception_handler.%E3%80%8D
http://study-ii.com/2014/08/laravel-error-in-exception-handler/
などに、対処方法があり、app/stroageの権限の問題かなと思いきや、すでに設定済みのため、
上記の方法では解決しなかった。
前提
app/config/app.php で 'debug' => falseにする。
app/start/global.php でHTTP errorのハンドリングをするようにしておく。
例えば、
// http error
$data = array();
App::error(function(Symfony\Component\HttpKernel\Exception\HttpException $e, $code){
if(File::exists(app_path() . '/views/errors/' . $code . '.blade.php')){
switch($code){
case 404:
Log::error('case 404');
break;
default: break;
}
return Response::view('errors.' . $code, $data, $code);
}else{
Log::error('file exists');
return Response::view('errors.500', $data, 500);
}
のように。
また、views/errors配下に404.blade.php,500.blade.phpを作成しておく。
原因
404.blade.phpは以下のように作成した。
@extends('common.layout')
<h1>404 not found</h1>
<h2>ページが見つかりません。</h2>
@stop
CMSなので、共通のレイアウトを読むこむようにした。
が、ここで気をつけなければいけないのは、common.layout内で使用している変数。
cssやjsのパスの設定や、CMSなのでログインしているユーザ名のための変数を使用しているが、
エラーハンドリングでは渡していなかったため、Response::viewを行った時に落ちてしまった。
対処方法
考えられる対処方法は、いくつもあるけど主に以下の2つ
対処方法1
404.balde.phpのレイアウトを変更して、common.layoutを呼ばないようにする。
CMSのレイアウトは捨てて完全に独自の404エラーページを作成してしまう。
欠点としては、cssやjsを使用する場合パスを直で書くことになるため、ファイルパスの変更を行った際に漏れる可能性があること。
対処方法2
\$dataに必要な分のデータを入れて渡す。
common.layoutや更にcommon.layoutで読んでいるテンプレート内で使用している変数をすべて
\$dataに入れて渡してあげる。こうすることで、404ページのデザインは変更せずに404ページを作成することができる。
まとめ
404.blade.phpで他のテンプレートを読んでいる場合は、そこで使われている変数も\$dataに入れて渡してあげないと、落ちるので各種エラーページを作成する際には気をつける。