EllisLab text mark
Advanced Search
     
Extending php Exception class… how to integrate into CI
Posted: 14 December 2007 08:39 PM
Joined: 2007-12-14
5 posts

Hi,

I am new to CI and would like to write custom exceptions (extend the PHP Exception class). How do I integrate custom exceptions into CI? Do I need to load the library with $this->load->library(“Exception_document_invalid_id”) in both the class that throws it and the class that traps it? How do I throw and trap it when its loaded (named) like this? I tried a few things but nothing worked. Any help would be most appreciated. Hopefully this can be done. Below is an example of what I am trying to do:

// the extended exception class (not the CI Exception class but the native PHP exception class)

class Exception_document_invalid_id extends Exception  {
     
public function __construct($id{
        
....
        
$code 101;
        
$message "Invalid document ID='" $id "'.";
        
parent::__construct($message$code); 
    
}
    
...
}

// the class throwing the custom exception

class Document_model extends Model 
{
    
....
    function 
get_document($id)
    

             
// test to see if document exists in DB, throw exception if not.
             
.....
             throw new 
Exception_document_invalid_id($id);
    
}
    
....
}

// the class trapping the exception

class Document extends Controller {
     
....
    function 
view()
    
{
              
try
              

                    
.....
                    
$this->load->model('Document_model');
                    
$document $this->Document_model->get_document($id);
                    .....
              

             
catch (Exception_document_invalid_id $ex)
             
{
                     $data[
'error_main'get_user_friendly_message($ex->getCode());
                     
log_message('error'"Document:view " $ex->getMessage(), false);
             
}
             
catch (Exception $ex)
             
{
                       $data[
'error_main'"Could not retrieve document. Unknown error.";
                       
log_message('error'"Document:view " $ex->getMessage(), false);
             
}
        }
       
....


Many thanks!
-d

 
Posted: 14 December 2007 09:03 PM   [ # 1 ]   [ Rating: 0 ]
Avatar
Joined: 2007-07-30
2144 posts

Name it MY_Exceptions.php, change your code a bit:

class MY_Exceptions extends CI_Exceptions { 

Save it to /applications/libraries/

 Signature 

Follow me on twitter here.
MichaelWales.com | MichaelWales.info

 
Posted: 14 December 2007 09:11 PM   [ # 2 ]   [ Rating: 0 ]
Joined: 2007-12-14
5 posts

Hi Michael,

Thanks for the reply! I am trying to extend the native php exception class (http://us2.php.net/exceptions) to create custom exceptions. How do I do this by extending the CI_Exceptions? This class seems to be the class for logging and showing errors.

Thanks!
-d

 
Posted: 14 December 2007 10:31 PM   [ # 3 ]   [ Rating: 0 ]
Joined: 2007-12-14
5 posts

I figured it out…. to use custom PHP exceptions in CI, you use Hooks. I basically followed the instructions for using the Zend Framework in CI (http://www.4webby.com/freakauth/tutorials/using-zend-framework-components-in-code-igniter) for my custom exception classes and it worked! You need to use “require_once” on the classes that throw the custom exception.

Thanks!
-d

 
Posted: 16 December 2007 03:55 AM   [ # 4 ]   [ Rating: 0 ]
Avatar
Joined: 2006-06-23
370 posts

Actually, Michael was trying to point you to the “CodeIgniter way” of doing this. If Hooks work for you, then great, but there’s also the ability to sub-class the core libraries.

 Signature 

Mac OS X 10.8, Apache 2.x, NGiNX, PHP 5.4.x, CodeIgniter 1.7.2/2.1.3

 
Posted: 16 December 2007 10:15 PM   [ # 5 ]   [ Rating: 0 ]
Joined: 2007-12-14
5 posts

I understand sub-classing the core libraries and have done so for some of the classes… I guess I don’t understand how to sub-class CI_Exceptions to get what I want. Or maybe I don’t understand what you are saying. I prefer to use the same style of exception handling I use in .NET—creating custom exceptions (extending the language’s exception classes) and using try/catch to trap exceptions. As far as I can tell, I cannot extend the CI_Exceptions class and get a custom exception that I can trap. If this can be done, it would be great if you could provide an example.

But maybe you mean I should extend the CI_Exceptions class by adding an array of exceptions and somehow handling the exceptions here and this would be in step with the CI way of handling exceptions (and backward compatible with PHP 4), i.e., 

class MY_Exceptions extends CI_Exceptions {
....
   var 
$exceptions = array(
    
E_CUSTOM_EXCEPTION_1    =>    'Custom message 1 here'
    
E_CUSTOM_EXCEPTION_2    =>    'Custom message 2 here',
    
E_CUSTOM_EXCEPTION_3    =>    'Custom message 3 here',
        ....
   );
....
 
Posted: 16 December 2007 11:13 PM   [ # 6 ]   [ Rating: 0 ]
Avatar
Joined: 2006-06-23
370 posts

You’re on the right track with that. You can do anything you want with your subclass.

1. override methods defined in the parent class
2. introduce new methods
3. define new class variables
4. define constants

PHP 5 introduces the set_exception_handler() function that you could utilize. CodeIgniter aims to remain compatible with PHP 4, so it doesn’t use this feature, but you could in your subclass. PHP 4 has the set_error_handler() function that might also be useful.

 Signature 

Mac OS X 10.8, Apache 2.x, NGiNX, PHP 5.4.x, CodeIgniter 1.7.2/2.1.3

 
Posted: 16 December 2007 11:59 PM   [ # 7 ]   [ Rating: 0 ]
Joined: 2007-12-14
5 posts

After reading a bit more on exception handling in PHP and looking at the CI code (specifically the set_error_handler callback function), I now understand what you are saying, especially the part about set_exception_handler(). Error handling in PHP is a little different from .NET and requires a different approach. I really appreciate all the help with this issue. This really clears things up.

 
Posted: 25 February 2008 11:40 AM   [ # 8 ]   [ Rating: 0 ]
Joined: 2007-12-07
113 posts

I also need to extend the CI_Exceptions class.

I named it MY_Exceptions.php and put it in /applications/libraries/

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

class 
MY_Exceptions extends CI_Exceptions{
    
    
function MY_Exceptions(){
        parent
::CI_Exceptions();
        
    
}

    
function show_404($page '')
    
{
    
echo 'test';
    
}

    
function show_error($heading$message$template 'error_general')
    
{
echo 'test';    
}

    
function show_php_error($severity$message$filepath$line)
    
{
         
echo 'test';
         
}
}
?> 

however, functions in MY_Exceptions do not seem to be overridden at all. functions in Exceptions are the one which are run

 Signature 

Atlantix Media Networks

 
Posted: 17 February 2010 04:35 PM   [ # 9 ]   [ Rating: 0 ]
Joined: 2006-09-02
24 posts

http://www.outofrepose.com/2010/02/17/extending-codeigniters-exceptions-class/

 Signature 

Bleh!

 
Posted: 10 November 2011 07:57 PM   [ # 10 ]   [ Rating: 0 ]
Joined: 2011-09-01
1 posts

For anyone who likes throwing different Exception types (EG: NotFoundException), I decided to define my class extensions in

core/MY_Exceptions.php

<?php
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class 
NotFoundException extends Exception {}
class EtcException extends Exception {}

class MY_Exceptions extends CI_Exceptions {
 
Posted: 07 June 2012 12:16 AM   [ # 11 ]   [ Rating: 0 ]
Joined: 2012-06-07
1 posts

This is an old post, but in case this helps someone.

When extending core classes you need to place your file in the application/core directory; not in the libraries folder. See http://ellislab.com/codeigniter/user-guide/general/core_classes.html. Your extended class will not get called otherwise.

Also, I believe the below needs a constructor something closer to this:

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

Hopefully that helps.

AtlantixMedia - 25 February 2008 11:40 AM

I also need to extend the CI_Exceptions class.

I named it MY_Exceptions.php and put it in /applications/libraries/

<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');

class 
MY_Exceptions extends CI_Exceptions{
    
    
function MY_Exceptions(){
        parent
::CI_Exceptions();
        
    
}
... 


however, functions in MY_Exceptions do not seem to be overridden at all. functions in Exceptions are the one which are run