Error handling with PHPMailer
PhpPhpmailerPhp Problem Overview
I'm trying to use PHPMailer for a small project, but I'm a bit confused about error handling with this software. Hoping someone has experience with it. When I've set up an email and I use:
$result = $mail->Send();
if(!$result) {
// There was an error
// Do some error handling things here
} else {
echo "Email successful";
}
Which works fine, more or less. The problem is when there's an error, PHPMailer also seems to echo the error out, so if there's a problem, it just sends that info directly to the browser, essentially breaking any error handling I"m trying to do.
Is there a way to silence these messages? Its not throwing an exception, its just printing out the error, which in my test case is:
invalid address: @invalid@email You must provide at least one recipient email address.
Its meant to be an error, but it should be residing in $mail->ErrorInfo; not being echo'd out by the software.
Php Solutions
Solution 1 - Php
PHPMailer uses Exceptions. Try to adopt the following code:
require_once '../class.phpmailer.php';
$mail = new PHPMailer(true); //defaults to using php "mail()"; the true param means it will throw exceptions on errors, which we need to catch
try {
$mail->AddReplyTo('[email protected]', 'First Last');
$mail->AddAddress('[email protected]', 'John Doe');
$mail->SetFrom('[email protected]', 'First Last');
$mail->AddReplyTo('[email protected]', 'First Last');
$mail->Subject = 'PHPMailer Test Subject via mail(), advanced';
$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!'; // optional - MsgHTML will create an alternate automatically
$mail->MsgHTML(file_get_contents('contents.html'));
$mail->AddAttachment('images/phpmailer.gif'); // attachment
$mail->AddAttachment('images/phpmailer_mini.gif'); // attachment
$mail->Send();
echo "Message Sent OK\n";
} catch (phpmailerException $e) {
echo $e->errorMessage(); //Pretty error messages from PHPMailer
} catch (Exception $e) {
echo $e->getMessage(); //Boring error messages from anything else!
}
Solution 2 - Php
You can get more info about the error with the method $mail->ErrorInfo
. For example:
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent';
}
This is an alternative to the exception model that you need to active with new PHPMailer(true)
. But if can use exception model, use it as @Phil Rykoff answer.
This comes from the main page of PHPMailer on github https://github.com/PHPMailer/PHPMailer.
Solution 3 - Php
Please note!!! You must use the following format when instantiating PHPMailer!
$mail = new PHPMailer(true);
If you don't exceptions are ignored and the only thing you'll get is an echo from the routine! I know this is well after this was created but hopefully it will help someone.
Solution 4 - Php
Just had to fix this myself. The above answers don't seem to take into account the
$mail->SMTPDebug = 0;
option. It may not have been available when the question was first asked.
If you got your code from the PHPMail site, the default will be
$mail->SMTPDebug = 2; // enables SMTP debug information (for testing)
https://github.com/Synchro/PHPMailer/blob/master/examples/test_smtp_gmail_advanced.php
Set the value to 0 to suppress the errors and edit the 'catch' part of your code as explained above.
Solution 5 - Php
We wrote a wrapper class that captures the buffer and converts the printed output to an exception. this lets us upgrade the phpmailer file without having to remember to comment out the echo statements each time we upgrade.
The wrapper class has methods something along the lines of:
public function AddAddress($email, $name = null) {
ob_start();
parent::AddAddress($email, $name);
$error = ob_get_contents();
ob_end_clean();
if( !empty($error) ) {
throw new Exception($error);
}
}
Solution 6 - Php
Even if you use exceptions, it still output errors.
You have to set $MailerDebug to False wich should look like this
$mail = new PHPMailer();
$mail->MailerDebug = false;
Solution 7 - Php
This one works fine
use try { as above
use Catch as above but comment out the echo lines
} catch (phpmailerException $e) {
//echo $e->errorMessage(); //Pretty error messages from PHPMailer
} catch (Exception $e) {
//echo $e->getMessage(); //Boring error messages from anything else!
}
Then add this
if ($e) {
//enter yor error message or redirect the user
} else {
//do something else
}
Solution 8 - Php
In PHPMailer.php, there are lines as below:
echo $e->getMessage()
Just comment these lines and you will be good to go.
Solution 9 - Php
$mail = new PHPMailer();
$mail->AddAddress($email);
$mail->From = $from;
$mail->Subject = $subject;
$mail->Body = $body;
if($mail->Send()){
echo 'Email Successfully Sent!';
}else{
echo 'Email Sending Failed!';
}
the simplest way to handle email sending successful or failed...
Solution 10 - Php
To address OPs problem:
> "PHPMailer also seems to echo the error out, so if there's a problem, it just sends that info directly to the browser, essentially breaking any error handling I"m trying to do."
It's not obvious (to me anyway, being new to exceptions) that all exceptions will be fed to the output buffer. Should somebody turn on debugging in production, front end users might get a surprise. I didn't want to leave that to chance. To add, the exception output was ending up in (and breaking) my JSON response, so it actually hindered my debugging.
My solution was to clean the buffer before returning the front end output. My use-case was a JSON response to a fetch API request, so before sending my output, I called ob_clean()
to clean the buffer of any unwanted debugging data. For example:
ob_clean(); //clean the buffer
echo json_encode( $public_output ); //echo response to browser
I should clarify that this is a fallback for potentially unwanted output and should not be a substitute for disabling the debugging. On the contrary, I imagine this may even be problematic for a dev expecting to see debugging output in the browser.
$mail->SMTPDebug = SMTP::DEBUG_OFF;
Finally, useful error output can still be sent to the logs even with debugging disabled:
error_log( $mail->ErrorInfo );