Viewed   643 times

I have a unique constraint on of the column. When this code runs, I get error log from framework but it is not what I have given in Exception block.
If unique column exists then I want to query its primary key and set it as $id and return to the page. Right now it is stopping on db error and not going into Catch block.
Here is my code:

try {
            $result = $this->db->insert('email', $new_email);
            if ($result)
            {
                $id = $this->db->insert_id();    
            } else {
                throw new Exception("$$$$$$$$$$$$$Log database error");
            }
        } catch (Exception $e) {
            log_message('error',$e->getMessage());
            return;
        }

**Error Messages** I get from framework:

DEBUG - 2013-04-07 05:00:38 --> DB Transaction Failure
ERROR - 2013-04-07 05:00:38 --> Query error: Duplicate entry 

I don't know what is wrong with it.

 Answers

1

CI has no good support for exceptions. You DB queries will call some vague CI error_logging thingie called show_error(). What you need to do is setup proper exception handling.

Basically you can follow the entire recipe.

Now all your database errors will automatically throw exceptions. And as a bonus you have good exception handling in your entire CI application.

Register a custom errorhandler that transforms PHP errors into exceptions, for instance put this in top of your config/config.php

function my_error_handler($errno, $errstr, $errfile, $errline)
{
    if (!(error_reporting() & $errno))
    {
        // This error code is not included in error_reporting
        return;
    }
    log_message('error', "$errstr @$errfile::$errline($errno)" );
    throw new ErrorException( $errstr, $errno, 0, $errfile, $errline );
}
set_error_handler("my_error_handler");

Register an uncaught exception handler, put something like this in your config/config.php

function my_exception_handler($exception)
{
    echo '<pre>';
    print_r($exception);
    echo '</pre>';
    header( "HTTP/1.0 500 Internal Server Error" );
}
set_exception_handler("my_exception_handler");

Set a termination handler:

function my_fatal_handler()
{
    $errfile = "unknown file";
    $errstr  = "Fatal error";
    $errno   = E_CORE_ERROR;
    $errline = 0;
    $error = error_get_last();
    if ( $error !== NULL )
    {
        echo '<pre>';
        print_r($error);
        echo '</pre>';
        header( "HTTP/1.0 500 Internal Server Error" );
    }
}
register_shutdown_function("my_fatal_handler");

Set a custom assert handler that converts asserts into exceptions, put something like this in your config/config.php:

function my_assert_handler($file, $line, $code)
{
    log_message('debug', "assertion failed @$file::$line($code)" );
    throw new Exception( "assertion failed @$file::$line($code)" );
}
assert_options(ASSERT_ACTIVE,     1);
assert_options(ASSERT_WARNING,    0);
assert_options(ASSERT_BAIL,       0);
assert_options(ASSERT_QUIET_EVAL, 0);
assert_options(ASSERT_CALLBACK, 'my_assert_handler');

Use wrappers like this in your controllers

public function controller_method( )
{
    try
    {
        // normal flow
    }
    catch( Exception $e )
    {
        log_message( 'error', $e->getMessage( ) . ' in ' . $e->getFile() . ':' . $e->getLine() );
        // on error
    }
}

You can tune and customize the whole thing to your likings!

Hope this helps.

You will also need to intercept the CI show_error method. Place this in application/core/MY_exceptions.php:

class MY_Exceptions extends CI_Exceptions
{
    function show_error($heading, $message, $template = 'error_general', $status_code = 500)
    {
        log_message( 'debug', print_r( $message, TRUE ) );
        throw new Exception(is_array($message) ? $message[1] : $message, $status_code );
    }
}

And leave in application/config/database.php this setting on FALSE to have database errors converted into exceptions.

$db['default']['db_debug'] = TRUE;

CI has a few (very) weak points, such as exception-handling but this will go a long way correcting that.

If you are going to use transactions, make sure you do rollbacks on exceptions. Related to this NEVER (as in EVER) use persistant connections as open transactions and other session specific DB state will be picked up / continued by other sessions.

Saturday, August 27, 2022
4

Hm, understand. As I see the subquery's source code in line 27, it wants to call _compile_select or get_compiled_select. If you can check in CI's DB_active_rec.php the _compile_select is protected so you can't access from Subquery (it isn't subclass of db).

Possible solution: _compile_select() should public or class Subquery should be extend of CI's db class. I think you should report this to author of Subquery.

Or you can extend the CI's db class :)

Sorry - I want to write it as a comment.

Sunday, December 18, 2022
 
ghazi
 
3

Try this code it might help you :

Here dashboard is the name of controller

//this will route as localhost/appFolder/admin/index
  $route['admin'] = 'dashboard'; // for your index page

//this will route as localhost/appFolder/admin/method_name
 $route['admin/(:any)'] = 'dashboard/$1';

//this will route as localhost/appFolder/admin/method_name/param1
$route['admin/(:any)/(:any)'] = 'dashboard/$1/$2';

Link the route Like

// for your index page
<a href="<?php echo base_url('admin/index'); ?>"></a>

// for your other pages
<a href="<?php echo base_url('admin/method_name'); ?>"></a>

To link the other controller defined just like

 <a href="<?php echo base_url('otherControllerName/method_name'); ?>"></a>
Sunday, September 4, 2022
 
3

See Handling Errors in Server-to-Server Remote Stored Procedures:

Calling RAISERROR with severity less than 20 from inside a remote stored procedure causes a statement abort error on the remote server. A TRY…CATCH construct on the local server handles remote batch abort errors only. If a remote stored procedure calls RAISERROR with severity less than 20 and the remote stored procedure is scoped within a TRY block on the local server, RAISERROR does not cause control to pass to the CATCH block of the TRY…CATCH construct. However, RAISERROR with severity 20 or greater on the remote server breaks the connection, and execution on the local server passes to the CATCH block.

Wednesday, November 23, 2022
 
3

When you enter a non-integer the Scanner call to nextInt() doesn't consume the non-integer. You need to call keyboard.next() (or keyboard.nextLine()) to consume it. Something like,

try {
    dim = keyboard.nextInt();
} catch (Exception e) {
    System.out.printf("%s is not an integer.%n", keyboard.next());
    err = 1;
}
Friday, September 30, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :