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 :)
Related
I have a list of Job IDs to check their status. So, I'm simply looping through all the Job IDs to get their status on Media Convert.
function get_aws_job_id_status($job_id)
{
$result = [];
$client = \App::make('aws')->createClient('MediaConvert', [
// 'profile' => 'default',
// 'version' => '2017-08-29',
'region' => 'region',
'endpoint' => "endpoint"
]);
try {
$result = $client->getJob([
'Id' => $job_id,
]);
return $result;
} catch (AwsException $e) {
return $result;
}
}
I'm using the above function inside the loop to get the status.
Referred to AWS Docs and Stackoverflow, but still, when I don't find a record for the given Job ID, it returns "NotFoundException" error that is not going in catch block and breaking the loop. Is there any way to handle that exception so I can continue the loop?
I believe you need to call Aws\MediaConvert\Exception\MediaConvertException and catch for MediaConvert specific errors. I don't see any of your use statements but I assume the code would look something like the following.
Note I am catching for all MediaConvert client errors, but I believe you could specifically call out the NotFoundException by doing Aws\MediaConvert\Exception\MediaConvertException\NotFoundException
use Aws\MediaConvert\MediaConvertClient;
use Aws\Exception\AwsException;
use Aws\MediaConvert\Exception\MediaConvertException as MediaConvertError;
function get_aws_job_id_status($job_id)
{
$result = [];
$client = \App::make('aws')->createClient('MediaConvert', [
// 'profile' => 'default',
// 'version' => '2017-08-29',
'region' => 'region',
'endpoint' => "endpoint"
]);
try {
$result = $client->getJob([
'Id' => $job_id,
]);
return $result;
} catch (MediaConvertError $e) {
/*Oh no, the job id provided ca not be found.
Let us log the job id and the message and return it back up to the main application
Note this assumes the main application is iterating through a list of JobIDs and
can handle this and log that job id was not found and will not have the normal Job
JSON structure.
*/
$error = array("Id"=>$job_id, "Message"=>"Job Id Not found");
$result = json_encode($error);
return $result;
}
}
Also keep in mind that if you are polling for job status's you may be throttled if your list grows too big. You would need to catch for a TooManyRequestsException [1] and try the poll with a back off threshold [2].
The most scalable solution is to use CloudWatch Events and track jobs based the STATUS_UPDATE, COMPLETE and ERROR status. [3]
[1] https://docs.aws.amazon.com/aws-sdk-php/v3/api/class-Aws.MediaConvert.Exception.MediaConvertException.html
[2] https://docs.aws.amazon.com/general/latest/gr/api-retries.html
[3] https://docs.aws.amazon.com/mediaconvert/latest/ug/monitoring-overview.html
I would like to delete other relations even if any of the previous deletions fail. I have used a lot of try/catch to achieve this. Is there a way I can reduce the amount of try-catch in my code or do it without try-catch?
public function delete_live_event(Request $request){
try{
$user = User::find($request->auth_user_id);
if(!$request->journey_item_id){
return response()->json(['StatusMessage' => 'Bir hata oluştu !', 'StatusCode' => 401,'error'=>'live_event_id gönderilmedi'], 401);
}
$journey_item = JourneyItem::find($request->journey_item_id);
if ($journey_item == null) {
return response()->json(['StatusMessage' => __('contents.not_found'), 'StatusCode' => 404], 404);
}
/** Assigned Users deleted **/
try{
UserJourney::where('as_journey_id',$journey_item->journey->id)->delete();
}catch (\Exception $e){ //log
}
/** journey deleted **/
try{
$journey_item->journey()->delete();
}catch (\Exception $e){
//Log
}
/** content deleted **/
try{
$journey_item->content()->delete();
}catch (\Exception $e){//Log
}
/** notifications deleted **/
try{
UserJourneyItemNotification::where('as_journey_item_id', $journey_item->id)->delete();
}catch (\Exception $e){//Log
}
/** item deleted **/
try{
$journey_item->item()->delete();
}catch (\Exception $e){//Log
}
/** journey_item deleted **/
$journey_item->delete();
return response()->json(['StatusMessage' => 'Live event is deleted succesfuly', 'StatusCode' => 200], 200);
}catch (\Exception $e){
//TODO error log
return response()->json(['StatusMessage' => 'Bir hata oluştu !', 'StatusCode' => 400], 401);
}
}
Try / Catch is usually used in a situation where you want to catch an error in order to stop further processing. If the each of the items in your list can be deleted, even if the others cannot be deleted, then there is no reason to use try/catch at all.
You also do not need to wrap your main function in try/catch block, as the only failure that would occur within that code is if you called a method that did not exist in your object. That would be a code failure, which would require correction. This is not the type of error that you would want to allow processing to continue, as the missing method is a code bug and should be corrected.
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?
I am working in PHP CodeIgniter and when I am trying to apply a try and catch block in my code then it is not working and does not handle the error. I have tried the try-catch block in both place Model and Controller but it is not working. My code is shown below.
try {
$data = array(
'userid' => '101',
'pass' => '123456',
'usertyp' => 2,
'createddate' => "now()");
$this->db->insert('login', $data);
}
catch (Exception $ex)
{
echo $ex;
}
Whatever the error occurred when I try to insert the record in database then it must be handled by the catch block but here it's not going happen.
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.