can't catch exception in codeIgniter - php

Sorry for my english but please i need help
i have a problem when i'm trying to catch an insert query
i have a table Employe with 3 primary keys (Matricule , CIN , name)
i want to catch the exception when i add a new employe with duplicated values
My Model
function insert_Employe($donnees){
try{
$this->db->insert('Employe',$donnees);
return 'employe enregistré avec succes';
}catch(Exception $e)
{
return $e->getMessage();
}
}
My controller
function nouveau(){
if(!$this->offres->_isLogged() || !$this->input->post('Ajax')==1){
redirect(base_url().'users');
}
$values = $this->_get_values();
try{
$message = $this->employe->insert_Employe($values);
echo $message;
}catch(Exception $e){
echo $e->getMessage();
}
}
i can't catch the exception

This will never throw an exception:
$this->db->insert('Employe',$donnees);
So you'll never catch an exception like that. If the insert() method fails it will generate display a custom error if $db['default']['db_debug'] is set to TRUE on database.config or simply return FALSE otherwise.
Your best bet is to check for errors when doing your DB operations:
$error = $this->db->_error_message()
if(!empty($error)) {
throw new Exception('Your message');
}

Related

How to catch SQL Exception in Laravel 5

Hay I'm creating a code like this :
\Log::info("saving log....");
try{
$data = AstronautCandidateLog::insert($request->logs);
}catch (SQLException $e)
{
\Log::info("SQL Exception happened");
}catch (Exception $e)
{
\Log::info("Exception happened");
}
\Log::info("status save data : ". $data);
But it seems that my Exception never get hit. So how to capture exception in laravel when something wrong in sql query...??
Thanks in advance.
Try this
try {
//Your code
} catch(\Illuminate\Database\QueryException $ex){
dd($ex->getMessage());
}
OR
use Illuminate\Database\QueryException;
try {
//Your code
} catch(QueryException $ex){
dd($ex->getMessage());
}
My case: add \ before Exception class otherwise it not handle
try
{
//write your codes here
}
catch(\Exception $e) {
Log::error($e->getMessage());
}
Make sure to use the Exception library in your controller. From there you can do:
try{
Some queries . . .
}catch(Exception $e){
return response()->json([
'error' => 'Cannot excecute query',
],422);
}
To implement an exception in Laravel, simply include the Exception class, at the top of your controller as
Use Exception;
Then wrap the lines of code you wish to catch an exception on using try-catch statements
try
{
//write your codes here
}
catch(Exception $e)
{
dd($e->getMessage());
}
You can also return your errors in json format, incase you are making an Ajax request, this time, remember to include the Response class at the top of your controller
Use Response;
Use Exception;
then wrap your codes in a try-catch statement as follows
try
{
//write your codes here
}
catch(Exception $e)
{
return response()->json(array('message' =>$e->getMessage()));
}
I hope this will solve your problem, you can learn more on Laravel and Error handeling here

Get all the exceptions from one try catch block

I wonder if it's posible to get all the exceptions throwed.
public function test()
{
$arrayExceptions = array();
try {
throw new Exception('Division by zero.');
throw new Exception('This will never get throwed');
}
catch (Exception $e)
{
$arrayExceptions[] = $e;
}
}
I have a huge try catch block but i want to know all the errors, not only the first throwed. Is this possible with maybe more than one try or something like that or i am doing it wrong?
Thank you
You wrote it yourself: "This will never get throwed" [sic].
Because the exception will never get thrown, you cannot catch it. There only is one exception because after one exception is thrown, the whole block is abandoned and no further code in it is executed. Hence no second exception.
Maybe this was what the OP was actually asking for. If the function is not atomic and allows for some level of fault tolerance, then you can know all the errors that occurred afterwards instead of die()ing if you do something like this:
public function test()
{
$arrayExceptions = array();
try {
//action 1 throws an exception, as simulated below
throw new Exception('Division by zero.');
}
catch (Exception $e)
{
//handle action 1 's error using a default or fallback value
$arrayExceptions[] = $e;
}
try {
//action 2 throws another exception, as simulated below
throw new Exception('Value is not 42!');
}
catch (Exception $e)
{
//handle action 2 's error using a default or fallback value
$arrayExceptions[] = $e;
}
echo 'Task ended. Errors: '; // all the occurred exceptions are in the array
(count($arrayExceptions)!=0) ? print_r($arrayExceptions) : echo 'no error.';
}

Yii transaction not rollbacked

i have the following piece of code and i pass it some data to generate an exception and test if the transaction rollback is happening. It seems it's not and i'm not sure why.
can someone help me? thanks
$transaction = Yii::app()->db->beginTransaction();
try {
//.....
//call private methods
$category = MyController::saveCategory($params);
$test_saved = MyController::saveTest($params);
MyController::saveCommunity($param); // here is an exception and it should rollback the transaction but it doesn't
$transaction->commit();
} catch(Exception $e) {
$transaction->rollback();
throw new Exception($e);
}
private function saveCommunity($param){
$community = new Community();
$community->user_id = $user_id;
$community->name = $name;
$community->id = 71; // this is a duplicate primary key and will generate an exception
try{
$community->save(false, null);
}catch(Exception $e){
throw $e;
}
return $community;
}
(mysql tables are set to innodb)
Try changing your code responsible for exception throwing:
try{
$community->save(false, null);
}catch(Exception $e){
throw $e;
}
to something like:
if(!$community->save(false, null))
throw new Exception('Error saving');
And remove the exception throwing here:
} catch(Exception $e) {
$transaction->rollback();
//throw new Exception($e);
}
By default pdo doesn't throw exceptions and just ignores errors.
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

catch exception in a fashionable way

I have an extended class for dateTime who makes some extra validation steps.
When a given date is invalid, it throws an exception.
Now I have some MySQL records with dates in zero (0000-00-00 00:00:00). In those cases, I want to show the text "never", so I have to catch the exception, and now I have this horrible mess...
try
{
$sellDate = new Date();
$sellDate ->setFromMySQL($this->_data['lastSell']);
$sellDateDMY = $dateSell->getDMY(TRUE);
}
catch (Exception $e)
{
if($e->getMessage() == 'Invalid date.')
$sellDateDMY = 'Never';
else
throw new Exception($e->getMessage());
}
$info[] = array('desc' => 'Last Sell: ' , 'data' => $sellDateDMY);
Any better way to do this?
Depends on which method it is that throws. The simplest would be to subclass Date again (maybe as NullableDate?) and override that method to not throw. The getDMY method would then return null, at which point you can display Never using the ternary operator ?:.
This way you won't have to use the ugly try/catch, and the intent of the code will also be clear to anyone who reads it for info on validation requirements -- by instantiating a NullableDate you definitely don't mind if its value is empty.
class DateException extends Exception {
public function __construct(Exception $e) {
if($e->getMessage() == 'Invalid date.') {
$this->message = 'Never';
} else {
$this->message = $e->getMessage();
}
}
}
try
{
$sellDate = new Date();
$sellDate ->setFromMySQL($this->_data['lastSell']);
$sellDateDMY = $dateSell->getDMY(TRUE);
}
catch (Exception $e)
{
throw new DateException($e);
}
You could start throwing different type of exceptions. Specific to the problem. Instead of the generic catch, you could do this
catch (DateInvalidException $de) {
//code
} catch (DateSomeOtherException $dso) {
//code
} catch (Exception $e) {
//general
}
But that's not a good solution. You're mixing up program exceptions and error validations.
Make your own Exception class for your Date functions.
class MyOwnDateException extends Exception {
... // Do something or probably nothing
}
And call it in your code:
try {
if($someErrorYouWantToCatch) {
throw new MyOwnDateException("error message", 100 /* Error code = optional */);
}
} catch(MyOwnDateException $mode) {
$sellDateDMY = 'Never';
}

PHP: catch exception in cascade. Is it possible?

I really need your help...
How can I catch exception in cascade?
I have a function ( A ) that call another function in another file ( B ) that call another function in another file ( C ).
How can I get in the catch of the function A, the errors of the function C?
Is it possible?
Look my example below... I tried to be the most clear possible...
// This code is in a file ( file A ) that call a function of a file B
require_once('/User_Login.php');
try
{
CREATE_NEW_User_Login(arr_Test, 'hello');
return true;
}
catch(Exception $e)
{
echo $e->getMessage();
return false;
}
}
// This code is in another file ( file B ) that call a function of a file C
public function CREATE_NEW_User_Login($_INPUT_Array = null, $_INPUT__Password = null)
{
// Db connection...
require_once('/User__DBclass.php');
$DBCl_User = new User($DBConn, null);
$DBCl_User->SET__CLASS_ATTRIBUTES_Value__by_Array($_INPUT_Array);
$DBCl_User->SETTER__user_pass(md5($_INPUT__Password));
$this->config['mysqli']->beginTransaction();
try
{
$DBCl_User->INSERT__NEW_ROW())
return true;
}
catch(Exception $e)
{
echo $e->getMessage();
return false;
}
}
// This code is in another file ( file C )
// In the User Class ( file: User__DBclass.php )
public function INSERT__NEW_ROW()
{
$this->config['stmt'] = $this->config['mysqli']->prepare('INSERT INTO tbl_user
SET user_id = :user_id,
user_name = :user_name,
act_code = :act_code;');
$this->config['stmt']->bindParam(':user_id', $this->user_id, PDO::PARAM_INT);
$this->config['stmt']->bindParam(':user_name', $this->user_name, PDO::PARAM_STR);
$this->config['stmt']->bindParam(':act_code', $this->act_code, PDO::PARAM_STR);
try
{
$this->config['stmt']->execute();
$this->user_id = intval($this->config['mysqli']->lastInsertId());
return $this->user_id;
}
catch(PDOException $e)
{
echo $e->getMessage();
return false;
}
}
If you want to cascade the exceptions, then you need to throw them again instead of just returning false.
You can either create a new exception type for each of your exception, or your can create a general exception and set the appropriate message and code.
catch(Exception $e)
{
//do something here if you want
throw $e;
}
Reference : http://php.net/manual/en/language.exceptions.php
Just don't catch the exception in the function where it is thrown. Then it'll be caught in your calling function.
This is the basic comportment of Exception : if you don't catch directly an exception this one is thrown to the upper element and so on to the "Root script".
Attention, you must catch the Exception, otherwise you'll get an error.
You can also "re"throwing an Exception from a catch block, like this:
catch(PDOException $e) {
throw $e;
}

Categories