I am trying to send email invitations with CakePHP (2.3.6) where a User enters a comma separated list of email addresses into an input field.
Currently, I can send emails without an issue as long as there is no invalid email address. However, I tried adding a Try/Catch to catch errors if there was a bad email, but my code is never hitting the catch.
Here is what I have
try {
if($Email->send()) {
$this->Session->setFlash(__('Email successfully sent'), 'flash/success');
} else {
$this->Session->setFlash(__('Could not invite guests. Please, try again.'), 'flash/error');
$this->redirect($this->referer());
}
} catch(Exception $e) {
$this->Session->setFlash(__('Could not invite guests. Probably a bad email. Please, try again.'), 'flash/error');
$this->redirect($this->referer());
}
$this->redirect($this->referer());
When I enter an invalid email with debugging on, I get the following error:
Invalid email: "foo"
Error: An Internal Error Has Occurred.
And when debugging is off:
An Internal Error Has Occurred.
I assumed there is something wrong with my Try / Catch, but it looks right to me. Is there some other method I should be going through to catch CakePHP errors?
Thanks in advance!!
Invalid email addresses cause the exception to be thrown right away when they are set. This occurs before the send method is called, so it is not reaching the try block you posted.
This is from a component I have written that handles sending several different emails for our system here. I have wrapped each address setting in a try block so the offending address can be more easily tracked down, but if you did not want that much detail you could wrap all of them in a single block. You can examine the message from the exception with the getMessage method to see the offending address string. This works for me with Cake 2.3:
$email = new CakeEmail();
//...
// set to for email
try
{
$email->to($recipient);
}
catch(SocketException $e)
{
$result['problem'] = 'Recipient Address';
$result['message'] = $e->getMessage();
return $result;
}
// set cc for email - not required
try
{
if($cclist != '') $email->cc(preg_split('/, */', $cclist));
}
catch(SocketException $e)
{
$result['problem'] = 'CC List';
$result['message'] = $e->getMessage();
return $result;
}
Check where exactly the exception causing this error is thrown, it is most likely not in the try block you've posted, but in one of the CakeEmail methods (from, sender, replyTo, etc...) that validates the address.
That being said, you should probably either wrap the single CakeEmail method calls into try catch blocks (in case you want to respond with proper error messages depending on which value exactly is wrong), or maybe use a single one that wraps all operations and output a generic error message.
Also note that CakeEmail::send() returns an array (containing header and message data), not a boolean, determining whether an E-Mail was send successfully must be done using try...catch, ie when no exception is being thrown, then the E-Mail was probably sent successfully.
Unfortunately the Cookbook is missing some proper examples. Here's some untested example code that should illustrate how it might work:
$Email = new CakeEmail();
try
{
$Email->from($from);
$Email->to($to);
// etc...
try
{
$Email->send();
$this->Session->setFlash(__('Email successfully sent'), 'flash/success');
}
catch(SocketException $e)
{
$this->Session->setFlash(__('Could not invite guests. Please, try again.'), 'flash/error');
}
}
catch(SocketException $e)
{
$this->Session->setFlash(__('Bad input'), 'flash/error');
}
$this->redirect($this->referer());
Related
The problem
I created a constraint in my SQL database to prevent duplicate entries. The initial laravel form submission works fine. I get back the correct message. When I try to throw a duplicate entry, the app, as expected, throws an error.
This is my Controller. A successful form submission does throw the correct error:
$contact->save();
return redirect('contactus.php')->with('status', 'We received your message. We will get back to you soon.');
return back()->withErrors(['Your message may be a duplicate. Did you refresh the page? We blocked that submission. If you feel this was in error, e-mail us or call us.']);
Question
How do I display that error on the HTML screen? Instead of having the page display the following?
Basically the contact form submits information into the database using laravel. When successful, it displays a success message by redirecting it. When not successful, (because of a SQL Unique constraint blocking duplicate entries) so far I've managed to make it throw a SQL error.
How do I display a custom message, like "post not successful, duplicate entry" in that case?
You can do it by using try catch and query exception:
try {
$contact->save();
return redirect('contactus.php')->with('status', 'We received your message. We will get back to you soon.');
} catch(\Illuminate\Database\QueryException $e){
$errorCode = $e->errorInfo[1];
if($errorCode == '1062'){
return back()->with('error', 'Your message may be a duplicate. Did you refresh the page? We blocked that submission. If you feel this was in error, e-mail us or call us.');
}
else{
return back()->with('error', $e->getMessage());
}
}
or another way you can find/check the data first, if already exist just send the error. example:
$contact = Contact::where('email',$request->email)->first();
if($contact)
{
return back()->with('error', 'Your message may be a duplicate. Did you refresh the page? We blocked that submission. If you feel this was in error, e-mail us or call us.');
}
dont forget to get the error on the form view using like below:
<script>
#if(session()->has('error'))
alert('{{session()->get('error')}}')
#endif
</script>
I have an array of emails. I would like to do some validation on each one to see if it is more or less the proper format. This script is validating emails for the administration side of a website. This particular piece of the administration side is for sending newsletters to particular groups, each containing an array of emails.
I am adding the functionality to add a group with administrator specified recipients. This would become useful if the administrator was getting rid of a particular group of newsletter recipients and wanted to add them to another group before destroying the original group.
I have come up with a way to throw an error if any of the items in the array do not match the validation, however, it seems like there should be a better way to do this in PHP. I have not been able to find an alternative method.
$email_array_data["count"] = count($email_array);
foreach($email_array as $email) {
if (email_validation_function($email) {
$email_array_data["passed_validation"]++;
} else {
$email_array_data["failed_validation"][] = $email;
}
}
if ($email_array_data["count"] == $email_array_data["passed_validation"]) {
Send The Emails
} else {
Echo The Emails That Failed Validation
}
This script works pretty well, but it seems like there would be a better way to do this that checking that every email met the requirements, then comparing the number of emails that passed/failed validation and the count of the emails array.
Is there a better method?
First, you should check out filter_var(). It's a great function for validating tons of data, especially emails (see here).
There are many ways to handle errors. Based on what I can see from your script, you are only considering the array valid if all emails are valid. You could throw an exception.
$is_valid = filter_var($email, FILTER_VALIDATE_EMAIL);
if( ! $email )
throw new Exception('Invalid email address supplied');
If you go this approach, you could catch the exception using a try {} catch {} Just another approach I guess.
I have been writing a custom auth provider in Symfony2. Everything works so far, but when I enter a wrong password a get an Internal Server error displaying: "LDAP authentication failed".
Now, this is the message that I want to display, but I'd like to display it above my login form and NOT throw an internal server error. In my listener, I have the following:
try {
$authToken= $this->authenticationManager->authenticate($token);
$this->securityContext->setToken($authToken);
return;
} catch (AuthenticationException $failed) {
throw new BadCredentialsException($failed->getMessage(), 0);
}
So is there anyone who can tell me what I need to do to show the user a message, instead of throwing an internal server error?
Thanks in advance.
You can manually add error to your login form in the controller. For example:
$form->get('username')
->addError(new FormError($message));
You should have a controler action that catch the same path of your form to catch the exception.
authentication process will be tryed before the form will be displayed.
You can see this example :
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Controller/SecurityController.php
I added validation on email input, but it is not working, why?
the error is that when I give input as example#yah.oo.com; not showing any error messages, why?
my code is
else if(!filter_var($email,FILTER_VALIDATE_EMAIL))
{
echo "email is not valid";
return false;
}
I also used preg_match function but the same problem occurs,
can any one tell me why it is not showing any validation message.
As of my knowledge, that an email address only contains one dot(.) is it
The validation is correct - your understanding is wrong. An email address of joe.soap#example.co.uk (two dots) is valid, as is joe.soap#email.example.co.uk (three dots), etc.
The only reliable way to validate an email address is to send a message to it.
You can make one yourself like the one below;
function checkEmail($email){
return eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email);
}
I am making a bitcoin faucet using the coinbase api, and was looking to validate the address. I looked online to see if there are any good scripts, and couldnt find any so I decided to test and see if it was already built in the API, and it was! The the thing is that instead of just saying that is not a valid address it php displays a LONG error...
Fatal error: Uncaught exception 'Coinbase_ApiException' with message 'Please enter a valid email or bitcoin address' in C:\xampp\htdocs\nahtnam\lib\Coinbase\Rpc.php:84 Stack trace: #0 C:\xampp\htdocs\nahtnam\lib\Coinbase\Coinbase.php(39): Coinbase_Rpc->request('POST', 'transactions/se...', Array) #1 C:\xampp\htdocs\nahtnam\lib\Coinbase\Coinbase.php(118): Coinbase->post('transactions/se...', Array) #2 C:\xampp\htdocs\nahtnam\faucet.php(54): Coinbase->sendMoney('17FSKMPAyXGR7EQ...', '0.00000555', 'this is a test') #3 {main} thrown in C:\xampp\htdocs\nahtnam\lib\Coinbase\Rpc.php on line 84
Is ther any way i can just set $address_error to "Please enter a valid Address" (not email) if this occurs and also not display the error? Thanks!
Expanding on aliasm2k's answer, you probably want to do it more like this:
EDIT: Changed answer slightly based on comments discussion
I think I was a bit unclear on what you were asking for in the comments.
try {
$result = $Coinbase->sendMoney($bitcoinaddress, '0.00000555', 'this is a test');
catch(Exception $e) {
echo $e->getMessage();
exit; //optional but you probably want to quit here and show the user
//the original form along with the error message to fix
}
This is just going to echo "Please enter a valid email or bitcoin address." You wont get all of that other info because you are catching the exception and just displaying the message.
Possible error messages are listed here.
Also, if I can give you a slightly off-topic hint:
If you want to find info about a particular address that has been used, try the blockchain block explorer api.
And to simply check if an address is valid, you need to calculate that in your code or find a library function to do so. There's no master-list of addresses that an api would have. The last 4 bytes of the address are a double-sha-256 checksum of the preceding characters. That's sort-of an imprecise description I'm giving you, by the way, but check here for a working php example
Use try and catch.
try {
if(/*invalid address check returns true*/)
throw 'Invalid address';
} catch(Exception $e) {
echo 'Exception: ' . $e->getMessage();
}