Domanda

I tried to follow the instructions here: http://kohanaframework.org/3.0/guide/kohana/tutorials/error-pages But for some reason I am unable to catch the HTTP_Exception_404 I still get a ugly error page and not my custom page.

Also when I type in the URL error/404/Message, I get a ugly Kohana HTTP 404 error message.

Here is the files structure:

  • modules
    • my
      • init.php
      • classes
        • controller
          • error_handler.php
        • http_response_exception.php
        • kohana.php
      • views
        • error.php

Code:

init.php:

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

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

http_response_exception.php:

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

class HTTP_Response_Exception extends Kohana_Exception {


    public static function exception_handler(Exception $e)
    {

            if (Kohana::DEVELOPMENT === Kohana::$environment)
            {
                    Kohana_Core::exception_handler($e);
            }
            else
            {
                    Kohana::$log->add(Kohana::ERROR, Kohana::exception_text($e));

                    $attributes = array
                    (
                            'action'  => 500,
                            'message' => rawurlencode($e->getMessage()),
                    );

                    if ($e instanceof HTTP_Response_Exception)
                    {
                            $attributes['action'] = $e->getCode();
                    }

                    // Error sub-request.
                    echo Request::factory(Route::url('error', $attributes))
                            ->execute()
                            ->send_headers()
                            ->response;
            }
    }
}

kohana.php:

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

class Kohana extends Kohana_Core
{

    /**
     * Redirect to custom exception_handler
     */
    public static function exception_handler(Exception $e)
    {
            Error::exception_handler($e);
    }

} // End of Kohana

error_handler.php:

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

class Controller_Error_handler extends Controller {

    public function  before()
    {
            parent::before();

            $this->template = View::factory('template/useradmin');
            $this->template->content = View::factory('error');

            $this->template->page = URL::site(rawurldecode(Request::$instance->uri));

            // Internal request only!
            if (Request::$instance !== Request::$current)
            {
                    if ($message = rawurldecode($this->request->param('message')))
                    {
                            $this->template->message = $message;
                    }
            }
            else
            {
                    $this->request->action = 404;
            }
    }

    public function action_404()
    {
            $this->template->title = '404 Not Found';

            // Here we check to see if a 404 came from our website. This allows the
            // webmaster to find broken links and update them in a shorter amount of time.
            if (isset ($_SERVER['HTTP_REFERER']) AND strstr($_SERVER['HTTP_REFERER'], $_SERVER['SERVER_NAME']) !== FALSE)
            {
                    // Set a local flag so we can display different messages in our template.
                    $this->template->local = TRUE;
            }

            // HTTP Status code.
            $this->request->status = 404;
    }

    public function action_503()
    {
            $this->template->title = 'Maintenance Mode';
            $this->request->status = 503;
    }

    public function action_500()
    {
            $this->template->title = 'Internal Server Error';
            $this->request->status = 500;
    }

} // End of Error_handler

I really cannot see where I have done wrong. Thanks in advance for any help.

È stato utile?

Soluzione 4

After a VERY LONG TIME of searching I finally found a solution to my little problem.

Here is a step by step tutorial on how to load your own custom error pages with Kohana 3.2:

  1. Change the environment variable in the bootstrap.

Here you have multiple options:

a. Do what they say in the documentation of the bootstrap.php:

/**
 * Set the environment status by the domain.
 */

if (strpos($_SERVER['HTTP_HOST'], 'kohanaphp.com') !== FALSE)
{
    // We are live!
    Kohana::$environment = Kohana::PRODUCTION;

    // Turn off notices and strict errors
    error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT);
}

b. Or just add those two lines without the "if":

Kohana::$environment = Kohana::PRODUCTION;
error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT);

c. I have not try this way but in the new bootstrap.php you have this code:

/**
 * Set Kohana::$environment if a 'KOHANA_ENV' environment variable has been supplied.
 *
 * Note: If you supply an invalid environment name, a PHP warning will be thrown
 * saying "Couldn't find constant Kohana::<INVALID_ENV_NAME>"
 */
if (isset($_SERVER['KOHANA_ENV']))
{
    Kohana::$environment = constant('Kohana::'.strtoupper($_SERVER['KOHANA_ENV']));
}

I assume that you could just give the value "production" to "$_SERVER['KOHANA_ENV']" before those lines.

Again, like I said I haven't tried it, but it should work.

I personally just commented out those lines of codes.

2 Now you need to add a few configurations in a "ini.php" file, or in the "bootstra.php" file.

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

/**
 * Turn errors into exceptions. 
 */
Kohana::$errors = true;

/**
 * Custom exception handler.
 */
restore_exception_handler();
set_exception_handler(array('Exception_Handler', 'handler'));

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

This is what was missing and made it to hard. For the rest you can easily just follow Kohana3.2 documentation or you can get the module that I added to a repo in GitHub: https://github.com/jnbdz/Kohana-error

Altri suggerimenti

First of all, you need to make sure you are loading your module by including it in the modules section of your application/bootstrap.php file like so

Kohana::modules(array(
'my'=>MODPATH.'my'
)
);

The fact that you mentioned going directly to the url for your error handler controller triggers a 404 error makes me think your module has not been loaded.

I would also suggest a few more changes.

http_response_exception.php does not need to extend Kohana_Exception, since this class is not an exception, but an exception handler. Along those same lines, a more appropriate class name might be Exception_Handler, since the class is not representing an exception, but handling them. Secondly, because of how you've named this file, it should be located in modules/my/classes/http/response/exception.php. Other than that, the code for this class looks ok.

Similarly, because of how you've named your controller, it should be located and named a bit differently. Move it to modules/my/classes/controller/error/handler.php

Remember that underscores in a class name means a new directory, as per http://kohanaframework.org/3.2/guide/kohana/conventions

Finally, I don't think you really need to extend the Kohana_Core class here, but instead just register your own custom exception handler. You can register your custom exception handler in either your application's bootstrap file, or in your module's init file with the following generic code:

set_exception_handler(array('Exception_Handler_Class', 'handle_method'));

Here's a customer exception handler I use, which is pretty similar to yours:

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

class Exception_Handler {

public static function handle(Exception $e)
{
    $exception_type = strtolower(get_class($e));
    switch ($exception_type)
    {
        case 'http_exception_404':
            $response = new Response;
            $response->status(404);
            $body = Request::factory('site/404')->execute()->body();
            echo $response->body($body)->send_headers()->body();
            return TRUE;
            break;
        default:
            if (Kohana::$environment == Kohana::DEVELOPMENT)
            {
                return Kohana_Exception::handler($e);
            }
            else
            {
                Kohana::$log->add(Log::ERROR, Kohana_Exception::text($e));
                $response = new Response;
                $response->status(500);
                $body = Request::factory('site/500')->execute()->body();
                echo $response->body($body)->send_headers()->body();
                return TRUE;
            }
            break;
    }
}

}

You're using an outdated documentation. HTTP_Exception_404 was bundled in 3.1, and you're trying to implement a solution from 3.0.

See documentation for your version of Kohana for a solution that works.

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>

Every underscore is a directory separator in a class name. So when naming your class Http_Response_Exception, the class should be in classes/http/response/exception.php. Otherwise the class will not be found by the autoloader of Kohana.

edit

Hmm, seems like the documentation is wrong in this aspect. classes/http_response_exception.php doesn't make sense.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top