Cakephp 3 get last query executed - php

I've been trying to handle exceptions on cakephp 3 when querying to database.
I would like to get the last query executed when and exception is fired to notify by email to an administrator, i'm using MySQL database so the error code would be nice to have it too if possible.
This is my code right now.
if($this->request->is('post')){
$opciones=$this->request->data;
$configsTable = TableRegistry::get('Configs');
try{
$configsTable->connection()->transactional(function() use($configsTable, $opciones){
foreach ($opciones as $llave => $opcion) {
$q = $configsTable->find('all', [
'conditions' => [
'Configs.nombre' => $llave
]
]);
$reg = $q->first();
if (empty($reg)) {
$data = array();
$data['nombre'] = $llave;
$data['valor'] = $opcion;
$entity = $configsTable->newEntity($data);
if (!$configsTable->save($entity, ['atomic' => false])) {
/********trying to catch database error here******/
throw new \Exception(__('Error message'));
}
}else{
$u = $configsTable->updateAll(['valor'=>$opcion], [
'id'=>$reg->id
]);
if(!$u){
/********trying to catch database error here******/
throw new \Exception(__('Error message'));
}
}
}
});
$this->Flash->success(__('Ajustes actualizados'),[
'params'=>['class'=>'alert-absolute timed', 'tiempo'=>5]
]);
} catch (\PDOException $ex) {
$this->Flash->error($ex->getCode().' - '.$ex->getMessage(),[
//'params'=>['class'=>'alert-absolute timed', 'tiempo'=>5]
]);
} catch (\Exception $ex){
$this->Flash->error($ex->getMessage(),[
//'params'=>['class'=>'alert-absolute timed', 'tiempo'=>5]
]);
}
}
I'm still searching on cookbook for some information. Thaks.

Let the PDOException be handled by the error handler (which is done by default). You can setup your own error handler which checks exception type and sends email in case of PDOException.
You can get the sql query using exception instance as $error->queryString.

Related

Laravel transaction does not rollback when none db exception happens

Here is my code:
DB::transaction(function () use ($r, $certificate, $candidate) {
UserCertificate::create([
'user_id' => $r['user_id'],
'certificate_id' => $certificate->id,
'issue_date' => Carbon::now()
]);
// create badge
$this->createCandidateBadge($candidate, $certificate);
});
An exception happens while creating the candidate badge: $this->createCandidateBadge
But when I see user_certificates table there is a certificate created! I don't want to create a certificate in DB unless a badge created successfully!
You can make customized transaction functionality and manual commit and rollbacks using try and catch blocks like this:
DB::beginTransaction();
try{
UserCertificate::create([
'user_id' => $r['user_id'],
'certificate_id' => $certificate->id,
'issue_date' => Carbon::now()
]);
// create badge
$this->createCandidateBadge($candidate, $certificate);
DB::commit();
}catch (\Exception $e){
DB::rollBack();
}
In case of exception of any type, it will be catched and then all db operations will be rollbacked. In case of no exception data will be saved.
According to the documentation Database Transactions,
If an exception is thrown within the transaction Closure, the
transaction will automatically be rolled back.
You should try to wrap your logic inside the DB::transaction by the try...catch, as follows:
DB::transaction(function () use ($r, $certificate, $candidate) {
try {
UserCertificate::create([
'user_id' => $r['user_id'],
'certificate_id' => $certificate->id,
'issue_date' => Carbon::now()
]);
// create badge
$this->createCandidateBadge($candidate, $certificate);
} catch (\Exception $e) {
// Response with Error here
}
});
// Response with success
Also check this question Laravel: Using try…catch with DB::transaction()
Enjoy :)

want to set exception for twilio

i am sending otp using twilio,laravel, message is working now, but i want to set exception for if message is not delivered etc i have tried like
public function send_otp()
{
try {
$account_sid = env('TWILIO_ACCOUNT_SID');
$auth_token = env('TWILIO_AUTH_TOKEN');
$number=Auth::user()->user_phone;
$client = new Client($account_sid, $auth_token);
$messages = $client->messages->create($number, array(
'From' => '+12533368077',
'Body' => Auth::user()->user_otp,
));
dd($messages);
//return $messages;
//throw new Exception();
} catch (Exception $e) {
return response()->json(['error' => true,'message'=>'Something went wrong'],200);
}
}
can you please help me with this
After setting env data did you clear cache?
php artisan config:cache
If you want to handle error - laravel has special logic for that. You need to just to catch that error and then make action, it is simple:
https://laravel.com/docs/5.6/errors
public function render($request, Exception $exception)
{
if ($exception instanceof CustomException) {
return response()->view('errors.custom', [], 500);
}
return parent::render($request, $exception);
}

Using exceptions in a production environment: Can a try catch block 'return' booleans?

The app is built on the MVC pattern, so my controllers are separate from my models.
I am using two payment gateways, Stripe and PayPal and have moved the API code into a model called Payment_Model.php.
Both functions have huge try/catch blocks that throw all manner of errors when a payment fails which is a good thing for me, not so for a customer...
Here is a try catch block example
try {
Stripe::setApiKey($this->config->item('stripe_secret_key'));
$customer = Customer::create([
'email' => 'customer#example.com',
'source' => $this->input->post('stripe_token'),
]);
$charge = Charge::create([
'customer' => $customer->id,
'amount' => $option->price,
'currency' => 'eur',
"description" => "Demo Transaction", // #TODO
]);
} catch (Exception $e) {
} catch (Stripe_CardError $e) {
throw new Exception($e);
} catch (Stripe_InvalidRequestError $e) {
throw new Exception($e);
} catch (Stripe_AuthenticationError $e) {
throw new Exception($e);
} catch (Stripe_ApiConnectionError $e) {
throw new Exception($e);
} catch (Stripe_Error $e) {
throw new Exception($e);
} catch (Exception $e) {
throw new Exception($e);
}
I don't want to display these errors or exceptions in my production environment... instead I would like to replace throw new Exception($e) with false so that I can call the model function in my controller and if something goes wrong I can redirect the user to a decent error page...
So my question is this:
Can I return a boolean IF something bad is caught so that I can either redirect to a success page or an error page in my controller? Or am I missing the point of using exceptions?

How can I make Symfony2 ignore Guzzle Client bad response exception in my custom controller?

function order_confirmationAction($order,$token) {
$client = new \GuzzleHttp\Client();
$answer = $client->post("http://www.fullcommerce.com/rest/public/Qtyresponse",
array('body' => $order)
);
$answer = json_decode($answer);
if ($answer->status=="ACK") {
return $this->render('AcmeDapiBundle:Orders:ack.html.twig', array(
'message' => $answer->message,
));
} else throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $answer->message);
}
If $client->post() response status code is an "Error 500" Symfony stops the script execution and throw new exception before the json decoding.
How can I force Symfony to ignore $client->post() bad response and execute till the last if statement?
$client = new \GuzzleHttp\Client();
try {
$answer = $client->post("http://www.fullcommerce.com/rest/public/Qtyresponse",
array('body' => $serialized_order)
);
}
catch (\GuzzleHttp\Exception\ServerException $e) {
if ($e->hasResponse()) {
$m = $e->getResponse()->json();
throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $m['result']['message']);
}
}
I solved like this. In that way I can access to responses of remote server even if it returns an error 500 code.
Per Guzzle documentation:
Guzzle throws exceptions for errors that occur during a transfer.
Specifically, if the API responds with a 500 HTTP error, you shouldn't expect its content to be JSON, and you don't want to parse it, so you're better off re-throwing an exception from there already (or informing the user that something went wrong). I would suggest trying this out:
function order_confirmationAction($order, $token) {
$client = new \GuzzleHttp\Client();
try {
$answer = $client->post("http://www.fullcommerce.com/rest/public/Qtyresponse",
array('body' => $order)
);
}
catch (Exception $e) {
throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $e->getMessage());
}
$answer = json_decode($answer);
if ($answer->status=="ACK") {
return $this->render('AcmeDapiBundle:Orders:ack.html.twig', array(
'message' => $answer->message,
));
} else {
throw new \Symfony\Component\HttpKernel\Exception\HttpException(500, $answer->message);
}
}
It is probably also a good idea to check for errors when JSON-decoding the response, because there could be surprises in the content you're getting (eg. wrong format, missing or unexpected fields or values, etc.).

Zend Framework 2 AbstractRestfulController - Exceptions as JSON

My goal is get a JSON like
{
"meta": {
"error_type": "error type",
"code": 400,
"error_message": "error msg"
}
}
In case something went wrong.
I tried to put the try catch block both in the rest controller's action and in the model but I get the whole exception stack (I mean with the layout + view)
What's the right way ?
Catch the exception in the controller action.
Return a JsonModel from the action containing exception information:
public function someAction()
{
try {
throw new Exception();
}
catch (Exception $e) {
return new JsonModel(array(
'meta' => array(
'code' => $e->getCode(),
'error_message' => $e->getMessage(),
//...
)
));
}
//...
}
Source: Returning JSON from a ZF2 controller action
[I tried to put the try catch block both in the action rest
controller]
I've just tried like
(I want my goal become true but
when only if something goes wrong :) )
public function create($data)
{
try{
$artist = $this->getRequest()->getPost('artist', null);
$title = $this->getRequest()->getPost('title', null);
$album = new Album();
$album->exchangeArray(array('artist'=>$artist,'title'=>$title));
$id = $this->getAlbumTable()->saveAlbum($album);
return $this->get($id);
}
catch (Exception $e) {
return new JsonModel(array(
'meta' =>array(
'code'=>500,
'error-num'=>$e->getCode(),
'error-msg'=>$e->getMessage(),
)
));
}
}
but as above it doesn't work
instead of json data i get the
whole default exception stack with layout.

Categories