CodeIgniter: Try Catch non funziona nel modello di classe

Ho un unique vincolo di colonna. Quando viene eseguito questo codice, ho il log di errore dal quadro, ma non è quello che mi hanno dato in blocco di Eccezione.

Se unica colonna esiste poi voglio query chiave primaria, e impostarlo come $id e tornare alla pagina. Adesso è ferma sui db di errore e non andare in Catch block.

Ecco il mio codice:

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** Mi da quadro:

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

Non so che cosa è sbagliato con esso.

  • Puoi dare una descrizione più specifica di che cosa esattamente non funziona? Cosa succede, invece di quello che ci si aspetta?
  • forse $risultato non è falsa?



5 Replies
  1. 27

    CI non ha un buon supporto per le eccezioni. Si query al DB chiamerà qualche vaga CI error_logging thingie chiamato show_error(). Quello che dovete fare è impostare un’adeguata gestione delle eccezioni.

    Fondamentalmente si può seguire l’intera ricetta.

    Ora tutti i tuoi errori di database automaticamente generare eccezioni. E, come bonus, si dispone di una buona gestione delle eccezioni in tutta la tua IC applicazione.

    Registrare un errorhandler che trasforma PHP errori in eccezioni, per esempio mettere questo in cima al tuo 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");

    Registrare un uncaught exception handler, mettere qualcosa di simile nella vostra 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");

    Impostare una risoluzione gestore:

    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 personalizzato affermare gestore che converte afferma in eccezioni, mettere qualcosa di simile nella vostra 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');

    Utilizzare il wrapper come questo nel vostro controller

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

    È possibile ottimizzare e personalizzare il tutto per i vostri gusti!

    Spero che questo aiuta.

    Si avrà bisogno anche di intercettare CI show_error metodo. Posto questo 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 );
        }
    }

    E lasciare in application/config/database.php questa impostazione FALSE per avere errori di database convertito in eccezioni.

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

    CI ha un poco (molto) punti deboli, come la gestione delle eccezioni, ma questo andrà un lungo cammino per la correzione.

    Se avete intenzione di utilizzare le transazioni, assicurarsi di fare il rollback sulle eccezioni. Correlati per questo MAI (come SEMPRE) utilizzare le connessioni persistenti come le transazioni aperte e altra sessione specifica DB di stato saranno prelevati /continua da altre sessioni.

  2. 1

    Se il database di debug è attivato, gli errori dal DB verrà inviato alle Eccezioni core di classe, e exit() è chiamato dopo, il che significa che lo script non potrà mai raggiungere il tuo if condizionale.

    Aprire application/config/database.php e provare a impostare db_debug false. Questa è una buona idea fare per la produzione di siti web, comunque, perché non si desidera che qualsiasi query SQL problemi a rilasciare informazioni circa la struttura del database.

    Anche, estranei, di prestare attenzione a utilizzare $ all’interno di virgolette, perché si otterrà analizzato come una variabile (anche un sacco di loro in una riga — si ‘ ll essere letteralmente una variabile variabile variabile variabile variabile variabile variabile variabile variabile variabile …).

  3. 1

    Che se si imposta il risultato al di fuori dell’ try blocco? O un operatore ternario:

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

    È difficile sapere senza sapere cosa sia il valore di $result è davvero, come @jcorry detto.

  4. 0

    Se si guarda in CodeIgniter del codice, vedrete che ha un suo errore di gestione istituito nel CodeIgniter.php in bot sistema/core e ci_system/cartelle principali.

    /*
     * ------------------------------------------------------
     *  Define a custom error handler so we can log PHP errors
     * ------------------------------------------------------
     */
        set_error_handler('_error_handler');
        set_exception_handler('_exception_handler');
        register_shutdown_function('_shutdown_handler');

    Le prime due funzioni di affrontare la gestione degli errori. Al fine di ottenere il blocco try..catch per il lavoro, basta disattivare questa.

    Utilizzando il restore_error_handler e restore_exception_handler funzioni, siamo in grado di ripristinare questi errori di gestione delle funzioni predefinite.

        restore_error_handler();
        restore_exception_handler();

    o… se si vuole preservare l’errore gestori per il ripristino in seguito.

        //Disable CodeIgniter error handling so we can use try catch blocks
        $errorHandlers = array();
        do {
            $errorHandler = set_error_handler(function() {}); //Get the current handler
            array_push($errorHandlers, $errorHandler); //Store the handler so that it can be restored if necessary
            for ($i = 0; $i < 2; $i++) { //We have to reset twice to get to the previous handler since we added a dummy handler
                restore_error_handler();
            }
        }
        while (!is_null($errorHandler)); //Is null when there are no handlers
        $exceptionHandlers = array(); //Do the same with exceptions
        do {
            $exceptionHandler = set_exception_handler(function() {});
            array_push($exceptionHandlers, $exceptionHandler);
            for ($i = 0; $i < 2; $i++) {
                restore_exception_handler();
            }
        }
        while (!is_null($exceptionHandler));
    
        try {
            //Your code goes here
        }
        catch (Error $e) {
            //Handle error
        }
        catch (Exception $e) {
            //Handle exception
        }
    
        //Restore all error handlers
        foreach ($errorHandlers as $errorHandler) {
            if (isset($errorHandler)) {
                set_error_handler($errorHandler);
            }
        }
        foreach ($exceptionHandlers as $exceptionHandler) {
            if (isset($exceptionHandler)) {
                set_exception_handler($exceptionHandler);
            }
        }

    Siamo in grado di disattivare tutte le custom gestori di errore e di memorizzarli per essere ripristinato, se desiderato.

    Io uso il loop quando il salvataggio e il ripristino nel caso ci sono altri gestori di errori di set up. In questo modo, il ripristino di tutti i gestori di errore, come ci può essere un codice simile altrove che risale ad un errore precedente gestore per scopi specifici e sarà conservata.

Lascia un commento