Error handling with PHPMailer

PhpPhpmailer

Php 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 );

PHPMailer Troubleshooting Wiki on GitHub

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStompedView Question on Stackoverflow
Solution 1 - PhpPhil RykoffView Answer on Stackoverflow
Solution 2 - PhpPhoneixSView Answer on Stackoverflow
Solution 3 - PhpPhilMDevView Answer on Stackoverflow
Solution 4 - PhpSimon RobertsView Answer on Stackoverflow
Solution 5 - PhpCharlie ShehadiView Answer on Stackoverflow
Solution 6 - PhpFredView Answer on Stackoverflow
Solution 7 - PhpPatdundeeView Answer on Stackoverflow
Solution 8 - PhpHaris ur RehmanView Answer on Stackoverflow
Solution 9 - PhpPrince-WView Answer on Stackoverflow
Solution 10 - PhpJeffersonView Answer on Stackoverflow