5

How can this be done? I'm trying to do this for about half an hour and it's getting pretty annoying. You would this this should be an basic and easy thing to setup for a framework like this. I hope maybe there's an easy way i missed, because i'm starting to thing i should not chose this framework at all if such basic tings are so hard to setup.

This is in my bootstrap.php file that should do the trick.

if ( ! defined('SUPPRESS_REQUEST'))
{
    /**
     * Execute the main request. A source of the URI can be passed, eg: $_SERVER['PATH_INFO'].
     * If no source is specified, the URI will be automatically detected.
     */ 
    $request = Request::instance();
    try
    {
        // Attempt to execute the response
        $request->execute();
    }
    catch (Exception $e)
    {
        if (Kohana::$environment === Kohana::DEVELOPMENT)
        {
            // Just re-throw the exception
            throw $e;
        }
        echo "ok";
        // Create a 404 response
        $request->status = 404;
        $view = View::factory('error404');
        $request->response = $view->render();
    }

    echo $request->send_headers()->response;
}

But i'm still getting

Fatal error: Uncaught Kohana_Request_Exception [ 0 ]: Unable to find a route to match the URI: test ~ SYSPATH\classes\kohana\request.php [ 674 ] thrown in C:\Xampp\htdocs\system\classes\kohana\request.php on line 674

instead of my custom 404 page. And yes, Kohana::$environment is set to Kohana::PRODUCTION;

It doesn't even get to the echo "ok"; part. Why doesn't the exception get caught?

daniels
  • 18,416
  • 31
  • 103
  • 173
  • 1
    Don't down vote just because i said i'm starting to think that i should no chose this framework, it's just that find this very weird and difficult to setup for such an easy thing. Now i'm looking for a solution so i can keep going, any ideea? – daniels Dec 16 '10 at 18:20
  • 1
    I'm afraid I haven't played with v3 yet. In v2 it's pretty easy using the event hook system. In any case, this forum page may apply to your case, especially the last 2 posts: http://forum.kohanaframework.org/discussion/4777/ko3-404/p1 – Fanis Hatzidakis Dec 16 '10 at 18:27
  • I did it using the catch all method. I've setup a catch all route, and in that controler just set the status to 404 and rendered my custom 404 view :D Thank you. You should make this an answer so i can accept it. – daniels Dec 16 '10 at 19:21
  • @daniels - I'm still looking for a simple way to do this. Anyway I must say that between the complex solutions I've found, I read that the catch-all-route method doesn't works 100% of the times. Here's reference where it explains why in the first paragraph and proposes another complex solution that's supposed to work better. http://kerkness.ca/kowiki/doku.php?id=routing:404_pages_by_catching_reflection_exception – Alejandro García Iglesias Apr 11 '12 at 16:35
  • The problem isn't Kohana, it's the documentation. Kohana is a good framework, it's just severely lacking in decent quality documentation. – Gavin Sep 17 '13 at 13:43

3 Answers3

7

Replace the last line of bootstrap.php with:

/**
* Set the production status
*/
define('IN_PRODUCTION', FALSE);

/**
* Execute the main request. A source of the URI can be passed, eg: $_SERVER['PATH_INFO'].
* If no source is specified, the URI will be automatically detected.
*/
$request = Request::instance();

try
{
    $request->execute();
}
catch (Kohana_Exception404 $e)
{
    $request = Request::factory('error/404')->execute();
}
catch (Kohana_Exception403 $e)
{
    $request = Request::factory('error/403')->execute();
}
catch (ReflectionException $e)
{
    $request = Request::factory('error/404')->execute();
}
catch (Kohana_Request_Exception $e)
{
    $request = Request::factory('error/404')->execute();
}
catch (Exception $e)
{
    if ( ! IN_PRODUCTION )
    {
        throw $e;
    }

    $request = Request::factory('error/500')->execute();
}

echo $request->send_headers()->response;

Create new controller "error.php":

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

class Controller_Error extends Controller {

    public function action_404()
    {
        $this->request->status = 404;
        $this->request->headers['HTTP/1.1'] = '404';
        $this->request->response = 'error 404';
    }

    public function action_403()
    {
        $this->request->status = 403;
        $this->request->headers['HTTP/1.1'] = '403';
        $this->request->response = 'error 403';
    }

    public function action_500()
    {
        $this->request->status = 500;
        $this->request->headers['HTTP/1.1'] = '500';
        $this->request->response = 'error 500';
    }
} // End Error

Create two files (exception404.php и exception403.php) in "kohana" folder:

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

class Kohana_Exception403 extends Kohana_Exception {

    public function __construct($message = 'error 403', array $variables = NULL, $code = 0)
    {
        parent::__construct($message, $variables, $code);
    }

} // End Kohana_Exception 403


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

class Kohana_Exception404 extends Kohana_Exception {

    public function __construct($message = 'error 404', array $variables = NULL, $code = 0)
    {
        parent::__construct($message, $variables, $code);
    }

} // End Kohana_Exception 404

Now you can manually throw 404 and 403 errors (you can't throw error 500 ;)

throw new Kohana_Exception404;
throw new Kohana_Exception403;
Konstantine Kalbazov
  • 2,643
  • 26
  • 29
  • 6
    If like me, you read this page and use Kohana 3.2 (or later), you will probably have to replace `Kohana_Exception404` with `HTTP_Exception_404`. – ereOn Jan 29 '12 at 16:01
6

All you need to do is set the path to a different view in your bootstrap.php add:

Kohana_Exception::$error_view = 'error/myErrorPage';

that will parse all the variables currently being parsed to the error page that lives in:

system/views/kohana/error.php

ie:

<h1>Oops [ <?= $code ?> ]</h1>
<span class="message"><?= html::chars($message) ?></span>
mdskinner
  • 498
  • 4
  • 12
  • What are the cons of this method? Why it has only few votes? It looks compact (just one string + one view file) and stable. – Haradzieniec Nov 13 '12 at 15:33
5

Since v3.1 the Kohana guide incldues a tutorial on custom error pages which show a much cleaner way of solving this question.

Lethargy
  • 1,859
  • 14
  • 15