Welcome Guest, Not a member yet? Register   Sign In
Catch DB error
#1

Hi,

I have a CI application that inserts data received from CSV files.
The CSV file contains table columns names that are used to create insert statements.

If there's an error in the table colums, the insert fails and generates an error.
However, I am not able to catch that error, and I get a system message.

I would like to be able to catch that error to be able to process it (to be able to send an email to indicate the insert failure).

Any idea how to do this ?


Cheers,
L@u
Reply
#2

You should validate the results.

I would suggest creating another table with just 2 colums: "column_name", "validation_rules". For each column in your original database you place one entry in the new table with a validation string (like: "required|greater_than[10]").

Now when you read the CSV you can check if the presented key (first row of CSV) exists in the validation table, if it does you can use the validation_rule to validate the value (other rows in CSV).

If it's valid then you can insert the data safely, if its not valid you could skip that file, only the row or send oud an email etc.
Reply
#3

What about exception handling? http://php.net/manual/en/language.exceptions.php

You're probably using some sort of recursion like foreach, for or while so you could try to process a table column but if something goes wrong, you hava a chance of handing the error with catch and then log the error and do whatever you want to do.
Best regards,
José Postiga
Senior Backend Developer
Reply
#4

@Diederik: the column name was just an example. I want to catch any DB error, for instance it could be losing the connexion, the table being dropped etc

@joespostiga: I've tried using the try/catch to get the exception ... but it the exception is not caught (probably none are thrown).

A few more details :
The model
PHP Code:
class P_model extends CI_Model{
    
// Insert a new row in table 
    
function insert($pRow) {
        return 
$this->db->insert'P'$pRow);
    } 

Extract of the controler :
PHP Code:
            if (($handle fopen('./Files/P.csv''r')) !== FALSE) {
                
fread($handle3); // Discard the BOM
                
$header fgetcsv($handle0$mySep); // First line is headers
                
$i=0;
                try {
                    while ( ((
$data fgetcsv($handle0$mySep)) !== FALSE) OR $myDBerror) {
                        
$myDBerror= ! $this->P_model->insert(array_combine($header$data));
                        
$this->firephp->log('myDBerror et i'$myDBerror$i);
                        ++
$i;
                    }
                } catch  (
Exception $e) {
                    echo 
'Received exception : ',  $e->getMessage(), "\n";
                } 

Note that neither the $myDBerror nor the try/catch trap the error !
As a matter of fact, the debug log ($this->firephp->log) is not run when an error is generated (hence $myDBerror is completely useless).

Any ideas ?


Cheers,
L@u
Reply
#5

Have you tried this way?

PHP Code:
if (($handle fopen('./Files/P.csv''r')) !== FALSE) {
 
   fread($handle3); // Discard the BOM
 
   $header fgetcsv($handle0$mySep); // First line is headers

 
   $i=0;

 
   while (($data fgetcsv($handle0$mySep)) !== FALSE) {
 
       try {
 
           $this->P_model->insert(array_combine($header$data));
 
       } catch (Exceptio $e) {
 
           $this->firephp->log('myDBerror et i'$myDBerror$i);
 
       }

 
       ++$i;
 
   }

Best regards,
José Postiga
Senior Backend Developer
Reply
#6

@josepostiga: I've just tried, and it's still the same thing !
Reply
#7

I've tracked down the problem to the display_error method in system/database/DB_driver class.
At line 1704 (last line of the method), there's :
PHP Code:
        exit(8); // EXIT_DATABASE 

So, no wonder each time there's a database error, the application does not go any further: it just stops there !

I commented out this line, and now I do receive an exception and the return of the insert method from my model returns true or false (according to success or failure).

May be that's something that should be considered in the standard CodeIgniter code base.


Cheers,
L@u
Reply
#8

(This post was last modified: 01-27-2016, 07:55 PM by Shawn.)

(01-22-2016, 08:18 AM)ComputingFroggy Wrote: I've tracked down the problem to the display_error method in system/database/DB_driver class.
At line 1704 (last line of the method), there's :
PHP Code:
exit(8); // EXIT_DATABASE 

So, no wonder each time there's a database error, the application does not go any further: it just stops there !

I commented out this line, and now I do receive an exception and the return of the insert method from my model returns true or false (according to success or failure).

May be that's something that should be considered in the standard CodeIgniter code base.


Cheers,
L@u


First off--bad idea to be changing the driver!
Instead, you need to set db_debug to false in your database.php in the config directory:
PHP Code:
'db_debug' => FALSE
This will stop codeigniter from displaying the error automatically

In your model function check for success and explicitly throw an error if the insert returns false.
PHP Code:
public function insert($pRow) {
    if (!
$this->db->insert'P'$pRow)) {
        
$error $this->db->error();
        throw new 
Exception('model_name->record: ' $error['code'] . ' ' $error['message']);
    }
    return 
TRUE

In your controller catch statement you want log the error->message, but not display it to the user, because it can
reveal details of your database that you may not want public.
PHP Code:
} catch  (Exception $e) {
     
log_message('error'$e->getMessage());
     echo 
'Received exception : ' 'friendly detail'"\n";
 } 
Reply




Theme © iAndrew 2016 - Forum software by © MyBB