Cakephp 3 Can't catch FatalErrorException - php

I have a function inside of a Component to send contact mail using Gmail. For whatever reason my work network is blocking the secure connection to Gmail if i use my phone internet for example it works fine so it's clear that the email configuration is fine. What i'm really interested is in catching that FatalErrorException so i can return false to the controller and show an error message in the web site but i'm failing to do so.
This is my code of the component:
try{
$correo = new Email();
$correo
->transport('mail')
->template('contacto_negocio')
->emailFormat('html')
->to($correoPara)
->from($correoDe, $nombreDe)
->replyTo($correoDe, $nombreDe)
->subject(__('Mensaje de contacto desde ').$sitio_nombre_secundario)
->viewVars([
'sitio_nombre_secundario'=>$sitio_nombre_secundario,
'sitio_nombre' => $sitio_nombre,
'nombreDe'=>$nombreDe,
'correoDe'=>$correoDe,
'mensaje'=>$mensaje
])
->send();
} catch (FatalErrorException $ex){
return false;
} catch(SocketException $ex){
return false;
}catch (\Exception $ex) {
return false;
}
And the code in the controller:
if($this->Correo->contactoNegocio($correo, $nombreDe, $correoDe, $mensaje)){
$respuesta = ['cod'=>1, 'mensaje'=>'Message sent'];
}else{
$respuesta = ['cod'=>0, 'mensaje'=>'<span style="color:red; font-size: 12px;">Message not sent.<span>'];
}
What i am missing??

Your code does not reach the point that it can catch FatalErrorException because the execution time error is more or less the result of a shutdown function that cake handles on its own.
You can increase the limit or try to modify their shutdown method, but you won't be able to "catch" this as an exception as it stops execution before the catch block.

Related

Is try catch block necessary inside controller in laravel?

I'm currently working on a project with my friend. He follows this method of writing codes. Is it good or bad? I'm also not that much experience developer.
public function store(Request $request)
{
try
{
$comment = new TicketComment();
$comment->content = $request['comment'];
$comment->user_id = Auth::user()->id;
$comment->ticket_id = $request['ticketId'];
$comment->save();
$ticket = Ticket::where('id', '=', $comment->ticket_id)->first();
$ticket->updated_at = $comment->created_at;
$ticket->update();
}
catch(Exception $e)
{
request()->session()->flash('unsuccessMessage', 'Failed to add comment !!!');
return redirect()->back();
}
request()->session()->flash('successMessage', 'Comment has been successfully added !!!');
return redirect()->back();
}
Don't have a broad Exception catch block. Only catch exceptions you expect to be thrown in that block that way you can properly log unexpected exceptions and fix any other bugs in your code that may have caused those, instead of hiding them from yourself.
If you must do this then it might be in the context of something like:
public function store(Request $request)
{
try
{
$comment = new TicketComment();
$comment->content = $request['comment'];
$comment->user_id = Auth::user()->id;
$comment->ticket_id = $request['ticketId'];
$comment->save();
$ticket = Ticket::where('id', '=', $comment->ticket_id)->first();
$ticket->updated_at = $comment->created_at;
$ticket->update();
}
catch(Exception $e)
{
if (!($e instanceof SQLException)) {
app()->make(\App\Exceptions\Handler::class)->report($e); // Report the exception if you don't know what actually caused it
}
request()->session()->flash('unsuccessMessage', 'Failed to add comment !!!');
return redirect()->back();
}
request()->session()->flash('successMessage', 'Comment has been successfully added !!!');
return redirect()->back();
}
This way any unexpected exceptions will still be reported and you can go through your logs later to fix any bugs that are causing them.
As a reminder since PHP 7.1 you can have a union of exceptions in a catch block (Reference) e.g.
try { }
catch (ExceptionType1|ExceptionType2 $e) {
}
This way you can handle the exceptions you know you can handle and let Laravel handle the ones you are not sure how to handle.
Note that you generally don't have to have try-catch blocks in controller code, you can always use the exception handler to do the flash/redirect back combination for all unhandled exceptions if that is your preferred way of handling them.
It is allways good to handle the errors. However, Laravel has built in error handling, which ease this process. This does not mean you dont need the try catch block.
Read more about laravel error handling: https://laravel.com/docs/5.8/errors
Even that laravel has his own built in error handling you better use try & catch.
Don't use it on development mode but on production mode. The use of try & catch is user friendly, which means that user will not see the traditional page with the error generated from laravel (in case of any error), but will see your default message.
Example of how to use it:
public function index()
{
try {
return view('index.blade.php');
} catch (\Exception $exception) {
\Log::error($exception);
return redirect()->back()->with(['message' => 'There was an error']);
}
}
If you see this part \Log::error($exception);, it means that the error generated from laravel will be registered on logs file under storage/logs/laravel.log so you as e developer can see the problem with that method. On the other part if something goes wrong with accessing the page: view('index.blade.php') the user will be redirected back to the previous page with a message saved in session, which is: 'There was an error'.
To catch the message in case of errors in your blade you should:
#if (session('message'))
<div class="container">
<div class="alert alert-danger text-center">{{ session('message') }}</div>
</div>
#endif
Happy coding!
here is how I handled the same. I logged the error instead of returning it to user interface.
public function postData()
{
try
{
//your logics to post goes here
}
catch (\Exception $exception) {
if (!($exception instanceof \SQLiteException)) {
app()->make(\App\Exceptions\Handler::class)->report($exception); // Report the exception if you don't know what actually caused it
}
Alert::toast('Error Toast', 'An error occurred');
\Log::error($exception);
return redirect()->back();
}
Alert::success('SuccessAlert', 'alert');
return back();
}

RabbitMQ connection lost while consuming messages

I am using RabbitMQ with PHP. While consuming messages from RabbitMQ, we have magic in this piece of code:
while (count($callbacks)) {
try {
$conn->wait();
} catch (Exception $e) {
//Log the message
}
}
This is working as infinite loop to receive messages as expected but what happening is if we lost connection to the RabbitMQ/RabbitMQ not up its going to catch block and returns nothing and printing bulk log messages. Is there any better way we can check for connection for RabbitMQ and stops the script? How can we achieve this? Any suggestions?
while (count($callbacks)) {
try {
$conn->wait();
} catch (Exception $e) {
//Log the message
break;
}
}

AWS SES Exception Handler - too many exceptions - error too long

I am using Amazon SES for sending emails, my final sending code being
try {
$result = $sesClient->sendEmail($email);
$messageId = $result->get('MessageId');
$result['success'] = $messageId;
} catch (Aws\Ses\Exception\SesException $e) {
$result['error'] = $e;
}
At the end of my query loop I want to gather all the errors and having them sent by email, but the problem is that only one error has about 7000 characters and that is because either if I catch Exception or Aws\Ses\Exception\SesException, I also get information from GuzzleHttp\Exception\RequestException: 'GuzzleHttp\Exception\ClientException' and many other infos which I do not realy need. Is there any way I can restrict the message with the main error message, which, in my case, was using an email with no #domain.com attached.
} catch (Aws\Ses\Exception\SesException $e) {
$result['error'] = $e->getMessage();
}

catching mailchimp php api errors

I am trying to create a subscribe method for my laravel app that uses the mailchimp api to subscribe a user to a given list. The method works fine when the email address is not already on the lsit. when it is already subscribed the mailchimp api throws the following error
Mailchimp_List_AlreadySubscribed blah#blah.co is already subscribed to
list Tc App Test List. Click here to update your profile.
with the following code being shown
public function castError($result) {
if($result['status'] !== 'error' || !$result['name']) throw new Mailchimp_Error('We received an unexpected error: ' . json_encode($result));
$class = (isset(self::$error_map[$result['name']])) ? self::$error_map[$result['name']] : 'Mailchimp_Error';
return new $class($result['error'], $result['code']);
}
I have attempted a try catch block to catch the error but it is still being returned to the browser, here is what I tried and were it says MailChimp_Error I tried with Exception as well.
public function subscribe($id, $email, $merge_vars)
{
try {
$this->mailchimp->lists->subscribe($id, $email, $merge_vars);
} catch (MailChimp_Error $e) {
$response = 'an error has occured';
}
return $response;
}
Ultimately I want to be able to run the method and then either return either a success message or a message describing the issue to the user. the 3 possible mailchimp method errors are Email_notexists, list_alreadysubscribed and list does not exist although tihs last one should not occur as I am providing the list in the source code.
edit 1; after being in touch with mailchimp api support they suggested this code but the error still gets returned to the browser in its entirety
try {
$results = $this->mailchimp->lists->subscribe($id, $email, $merge_vars);
} catch (Mailchimp_Error $e) {
if ($e->getMessage()) {
$error = 'Code:'.$e->getCode().': '.$e->getMessage();
}
}
echo $error;
You can do
try
{
$response = $this->mailchimp->lists->addListMember($list_id, [
"email_address" => $email,
"status" => "subscribed",
]);
}
catch (\EXCEPTION $e) {
return $e->getMessage();
}
The \EXCEPTION handles a sort of error for stripe
Subscribe is in a namespace Acme\Emails\Subscribe so catch(Mailchimp_Error $e) looks for Mailchimp_Error in this namespace.
Changing it to catch(\Mailchimp_Error $e) makes it look in the root namespace and then it works as intended

Balanced Payments PHP Client: query result triggers uncaught exception

I'm trying to query a marketplace for an account that matches an e-mail address, and when it can't find a result, it's raising an uncaught exception despite my try/catch block.
try {
$vendor = $this->marketplace ->accounts ->query()
->filter(Balanced\Account::$f->email_address->eq($this->vendor['email']))
->one();
$this->balanced_vendor = $vendor;
return true;
} catch (Balanced\Exceptions\HTTPError $e) {
$this->notify('no-vendor', $e);
}
What might i be doing wrong ?
Thanks !
Looks like the Balanced\Core\Query class throws both Balanced\Exceptions\MultipleResultsFound and Balanced\Exceptions\NoResultFound from its one() method, not Balanced\Exceptions\HTTPError.
To fix your immediate problem, you should change your catch directive to:
} catch (Balanced\Exceptions\MultipleResultsFound $e) {
// handle multiple results..
} catch (Balanced\Exceptions\NoResultsFound $e) {
$this->notify('no-vendor', $e);
}
From the looks of it though, you attempted to use the Balanced\Exceptions\HTTPError as a catch all, which can be considered a lacking feature of the client. What I've done, is I've filed a Github issue for you that suggest all exceptions inherit from a base Balanced exception.
I hope this helps.

Categories