Overriding Kohana_Exception::_handler() for Production - 3.3
Asked Answered
W

2

5

I am using Kohana 3.3 and I read in this forum post.

It says that to prevent stack traces from being shown to the end users, I need to override Kohana_Exception::_handler() to do something different with the errors that percolate up. Does that mean overriding Kohana_Exception and adding the following function?

public static function _handler(Exception $e)
{
    try
    {
        // Log the exception
        Kohana_Exception::log($e);

        // Generate the response
        //instead of below line:
        //$response = Kohana_Exception::response($e);
        $response = //what do I do here, return a 404 page or custom 500 page?
        return $response;
    }

    //rest of function
}

If so, what do I return there?

EDIT:

bootstrap.php

/**
 * Attach the file write to logging. Multiple writers are supported.
 */
Kohana::$log->attach(new Log_File(APPPATH.'logs'));

/**
 * Attach a file reader to config. Multiple readers are supported.
 */
Kohana::$config->attach(new Config_File);

/**
 * Attach customer error handler if we are in production
 */
if(Kohana::$environment == Kohana::PRODUCTION || Kohana::$environment == Kohana::STAGING)
{
    set_exception_handler(array('My_Exception', 'handler'));
    throw new Exception('text'); //this works, if removed however my  exception handler does not do anything
}

My_Exception.php (in classes/My/Exception.php)

<?php   
    class My_Exception extends Kohana_Exception 
    {
        public static function handler(Exception $e)
        {
            try 
            {
                // Log the exception
                Kohana_Exception::log($e);

                // Let's try and load an error View             
                $class = get_class($e);

                if($class == 'HTTP_Exception_404')
                {
                    $view = View::factory('errors/404');
                    $view->set('error_code', 404);
                }
                else
                {
                    $view = View::factory('errors/general');
                    $view->set('error_code', $e->getCode()); // alternatively use $e->getCode()
                    $view->set('error_message', $e->getMessage()); // alternatively use $e->getMessage();
                }

                // Let's render the output and send it to the browser
                $response = $view->render();
                echo $response;
            }
            catch (Exception $e)
            {
                /**
                 * Things are going *really* badly for us, We now have no choice
                 * but to bail. Hard.
                 */
                // Clean the output buffer if one exists
                ob_get_level() AND ob_clean();

                // Set the Status code to 500, and Content-Type to text/plain.
                header('Content-Type: text/plain; charset='.Kohana::$charset, TRUE, 500);

                // This will output the Exceptiones error message
                // You may want to display something else
                echo $e->getMessage();

                exit(1);
            }
        }
    }
Wallinga answered 19/2, 2013 at 21:59 Comment(0)
I
10

I have actually investigated quite a bit further this issue and rewritten my asnwer from scratch now that I have a more complete understanding of Kohana's behaviour in this area.

To achieve what you're after you need to do two things:

  1. Change the default error View (in APPPATH/bootstrap.php):

    /**
     * Change default error View
     */
    if(Kohana::$environment == Kohana::PRODUCTION || Kohana::$environment == Kohana::STAGING)
    {
        Kohana_Exception::$error_view = 'errors/general';
    }
    

    Note that your template file has to use the same (and only those) variable names as Kohana's native one, i.e.:

    • $class
    • $code
    • $message
    • $file
    • $line
    • $trace

  2. Create custom HTTP error pages following the tutorial you linked to in the comments.

By following these steps you assure that:

  • You have your own view for all Kohana's error pages.
  • You can have custom views for different HTTP errors.
  • You don't have to override Kohana's default Exception Handler (which, as this exercise proved, isn't exactly simple to implement).

I have tested the above approach and it worked like a charm for me.

Irretentive answered 20/2, 2013 at 8:43 Comment(5)
Would this take precedence over (and it is it a better solution?) including my own Custom Error Pages as explained here: kohanaframework.org/3.3/guide/kohana/tutorials/…Wallinga
It not only takes precedence but completely overrides the Custom Error Pages approach AFAIR. Is it better? It's different because it catches all errors that occur during execution, not just those thrown by HTTP_Exceptions. Give it a try and see if it works for you.Irretentive
Hmm, if there are parse errors, the Kohana default exception handler is still doing stuff. put the set_exception_handler after init, log and config files are attached, but my error handler only seems to work if I thrown an exception right after setting it. Code in edit.Wallinga
I have completely revisited my answer. Have a look - should now solve your problem.Irretentive
Yup, worked for me as well. Thank you for having the tenacity to come back with a revised answer. Much appreciated.Wallinga
M
0

I just set the Kohana_Exception::$error_view at the bootstrap file, and created the corresponding view, nothing else was necessary, all errors have redirected auto-magically...

Muslim answered 1/12, 2013 at 21:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.