もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

Cakephp3のカスタムエラーページ作成

cakephp3ネタ続いてます。

今ガッツリやり始めてるので、気になったことはどんどん上げていく所存。

今回はエラーハンドリング。

公式見ればだいたい分かるけど、まとめとして書いときます。

Template/Error/error400.ctpとかerror500.ctpとか用意すればとりあえず表示されるけど、レイアウトも変えたいときは、独自のレンダラーを作成するっぽい。

1. config/app.php

<?php

...


    'Error' => [
        'errorLevel' => E_ALL,
        'exceptionRenderer' => 'App\Error\AppExceptionRenderer', ←ここを変更
        'skipLog' => [],
        'log' => true,
        'trace' => true,
    ],

2. App/Error/AppExceptionRenderer.php

<?php

namespace App\Error;

use Cake\Error\ExceptionRenderer;

class AppExceptionRenderer extends ExceptionRenderer
{
    /**
     * レイアウトを切り替える
     */
    public function render()
    {
        $this->controller->viewBuilder()->setLayout('error_layout');
        return parent::render();
    }
}

3. App/Template/Layout/error_layout.ctp

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <title>エラー!!</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" />
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
    <script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
  <main>
    <?php echo $this->fetch('content'); ?>
  </main>
</body>
</html>

4. App/Template/Error/error500.ctp

<div class="container">
    <div class="row">
        <div class="panel panel-danger">
            <div class="panel-heading">
                <h3 class="panel-title">Error!!!500</h3>
            </div>
            <div class="panel-body">
                <?php echo $message; ?>
            </div>
        </div>
    </div>
</div>

こんな感じで用意して、適当にエラー出してみる。

f:id:kojirooooocks:20180426010726p:plain

できた。

ちなみにerror500.ctpで表示しようとしている $messageAppExceptionRendererが継承している ExceptionRendererのrender()メソッド内で、catchしたExceptionの情報をtemplateに送ってくれているので、取れる。

f:id:kojirooooocks:20180426010737p:plain

↑みたいな感じで、色々セットしてくれている。

お客さんが使うような環境の場合は流石にエラーメッセージ見せるわけには行かないけど、管理画面の本番環境とかの場合は、xdebugとか起動させてない可能性があるから、こんな感じで穏当なエラーページ出して、エラー内容書いとけば、ササッと修正できそう。

ExceptionRendererが持っている$this->controllerは実行されているControllerになるので、それがPluginのControllerの場合は、テンプレートやレイアウトも各pluginのものになる。

pluginで環境を分けてる場合とかは地味に便利!

こんな感じでした。 おわり。