How about remove every exit after show_error()? #1833

Closed
dionysiosarvanitis opened this Issue Sep 27, 2012 · 4 comments

Comments

Projects
None yet
3 participants
Contributor

dionysiosarvanitis commented Sep 27, 2012

I think that by removing every exit right after show_error() it could be possible to override it and handle the error from within web application.

Contributor

dionysiosarvanitis commented Oct 2, 2012

There is a better approach for this (no need to remove anything). We can override show_error() and throw an extended Exception called NativeException similar to CI's logic. Also, by setting a default exception_handler, catching the NativeException inside the application flow is not mandatory. Everything works just like before plus we've added the ability to handle the error from within our application.

class CIRuntimeException extends Exception {

    protected $heading;
    protected $template;
    protected $status_code;

    public function __construct($heading, $message, $template = 'error_general', $status_code = 500, $code = 0, Exception $previous = null)
    {
        parent::__construct($message, $code, $previous);

        $this->heading      = $heading;
        $this->template     = $template;
        $this->status_code  = $status_code;
    }

    final public function getHeading(){ return $this->heading; }
    final public function getTemplate(){ return $this->template; }
    final public function getStatus(){ return $this->status_code; }
}
class MY_Exceptions extends CI_Exceptions {

    var $ci;

    function __construct()
    {
        parent::__construct();
        $this->ci =& get_instance();

        set_exception_handler(array($this, '__exception_handler'));
    }

    /**
     * General Error Page
     *
     * This function takes an error message as input
     * (either as a string or an array) and displays
     * it using the specified template.
     *
     * @access  public
     * @param   string  the heading
     * @param   string  the message
     * @param   string  the template name
     * @param   int     the status code
     * @return  string
     */
    function show_error($heading = 'Uncaught exception', $message, $template = 'error_general', $status_code = 500)
    {
        set_status_header($status_code);

        $message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';

        throw new CIRuntimeException($heading, $message, $template, $status_code, E_ERROR);
    }


    /**
    * Default Exception Handler
    * Triggers on uncaught exceptions
    *
    * @access   private
    * @return   void
    */
    function __exception_handler($exception)
    {
        $heading = $exception->getHeading();
        $message = $exception->getMessage();

        parent::log_exception(E_ERROR, $message, $exception->getFile(), $exception->getLine());

        set_status_header($exception->getStatus());

        if($this->ci->input->is_ajax_request())
        {
            //echo $this->ci->template->message($message, 'error');
            echo $message;
        }
        else
        {   //output rendered template
            if (ob_get_level() > $this->ob_level + 1)
            {
                ob_end_flush();
            }
            ob_start();
            include(APPPATH.'errors/'.$exception->getTemplate().'.php');
            $buffer = ob_get_contents();
            ob_end_clean();

            echo $buffer;
        }

        exit;
    }
}
Contributor

alexbilbie commented Oct 2, 2012

Can you please submit this as a pull request so we can discuss your code suggestions

Contributor

ckdarby commented Oct 2, 2012

@dionysiosarvanitis Any reason to why you closed the issue instead of making the pull request?

Contributor

dionysiosarvanitis commented Oct 4, 2012

Actually the reason is that CI is a lot far away from creating Exception Classes. But as you never know here is my pull request #1849.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment