/404, 500, custom, error, exception, kohana, PHP

Custom error pages in Kohana v3.x

Kohana framework displays really nice and descriptive error messages, for a development environment that is. For production, obviously no error reports should be shown to the user. Instead we should display a pretty "404 Not Found" page, or some other error page.
Creating those custom error pages in Kohana v3.x can be a real pain in the bum. I’m hoping that below guide will help you get this done in just few minutes.

Create HTML of your custom pages

Start with creating a 404.php file here:

/application/views/error/404.php

Add content you want, for example

<h1>My custom 404 error page!</h1>

Repeat the same for a 500 error page
File: /application/views/error/500.php
Code: <h1>My custom 500 error page!</h1>

Following the same pattern, you can create custom pages for all error codes. If you want one error page for all just create it and later point all requests to that view.

Create template if you need it

You can use the same template you’re using for your normal pages. If so, feel free to omit this step.

File: /application/views/error.php
Code: <?php echo $content; ?>

Extend Kohana exception class

Create directory and file as per below and copy code into the file.

File: /application/classes/kohana/exception.php
Code:

<?php defined('SYSPATH') or die('No direct script access.');

class Kohana_Exception extends Kohana_Kohana_Exception {
  public static function handler(Exception $e) {
    if (Kohana :: $environment === Kohana :: DEVELOPMENT) {
      // In development show normal Kohana errors
      parent :: handler($e);
    } else {
      // In production show custom error page
      try {
        Kohana :: $log->add(Log :: ERROR, parent :: text($e));
        $attributes = array (
          'action' => 500,
          'message' => rawurlencode($e->getMessage())
        );
        if ($e instanceof HTTP_Exception) {
          $attributes['action'] = $e->getCode();
        }
        // Error sub-request.
        echo Request::factory(Route::get('error')->uri($attributes))->execute()->send_headers()->body();
      } catch (Exception $e) {
        // Clean the output buffer if one exists ob_get_level() and ob_clean();
        // Display the exception text
        echo parent :: text($e);
        // Exit with an error status exit (1);
      }
    }
  }
}

Add route for error pages

File: /application/bootstrap.php
Code:

Route::set('error', 'error/<action>/(<message>)', array('action' => '[0-9]++', 'message' => '.+'))
  ->defaults(array( 'controller' => 'error', 'action' => '404' ));

Finally, create controller for error pages

File: /application/controller/error.php

<?php defined('SYSPATH') or die('No direct script access.');

class Controller_Error extends Controller_Template {
  // if you've created your custom error template. If not use your standard template here.
  public $template = 'error';
  public function before() {
    parent :: before();
  }
  /** * Serves HTTP 404 error page */
  public function action_404() {
    $this->template->content = View :: factory('error/404');
  }
  /** * Serves HTTP 500 error page */
  public function action_500() {
    $this->template->content = View :: factory('error/500');
  }
}

That’s it. Try to access a page on your site that doesn’t exist and you should see your custom 404 error page. Remember, when working in development standard Kohana errors will be shown and only on production our pretty error pages will shine. Line 6 in exception.php controls this behaviour.

Above is simplified and slightly modified version of Lysender post.