Search code examples
phpemailphpmailer

Problem catching and displaying errors when using phpmailer


I have a simple HTML contact form that uses a server-side PHP file to send mail using PHPMailer codes. Everything works very smooth and I am able to get a confirmation of all successful mail transmission.

The problem I have is that I am only able to capture and redirect the success mail transmission messages but not the failure messages. What I did is I used the PHPMailer recommended "try and catch" method to capture the errors and then a conditional if statement to test the $mail->send() value for true and false to determine whether the mail was sent successfully and directing the page accordingly to my error or success pages.

It should be noted that I am testing this as a non-ajax backup method in case the user disable JavaScript on the client-side. The ajax method is working fine.

I tried to simulate mail sent failure by sending the form without an internet connection or disabling some of the codes in the PHP file like "$mail->Port", or "$mail->Host", even the gateway password. The conditional statement I have always render a "false" value causing the success message to be displayed.

Below is the pertinent part of my PHP code:

/* Create a new PHPMailer object. Passing TRUE to the constructor enables exceptions. */
$mail = new phpmailer( TRUE );
//
/* Open the try/catch block. */
try {
//
/* Set the mail sender. */
$mail->setFrom( '[email protected]', 'mail-sender name' );
//
/* Add a recipient. */
//set who is recieving mail
$mail->addAddress( '[email protected]' );
//
/* Set the subject. */
$mail->Subject = 'New Order Request Message';
//
/* Set email to be sent as HTML */
$mail->isHTML( true );
//
/* Set the mail message body. */
$mail->Body = "<h3>New Order Request Message.</h3>
<style>
table, {
border: 1px solid black;
background-color: #f8f9f9 ;
}
}
td {
padding: 5px;
}
</style>
<div>
//
<table>
<tr>
<td>First Name: </td>
<td>$firstName</td> 
</tr>
<tr>
<td>Last Name: </td>
<td>$lastName</td> 
</tr>
<tr>
<td>Email: </td>
<td>$email</td>
</tr>
<tr>
<td>Telephone: </td>
<td>$telephone</td>
</tr>
<tr>
<td>Message: </td>
<td>$message: </td> 
</tr>
</table>
//
</div>";
//
/* SMTP parameters. */
/* Tells PHPMailer to use SMTP. */
$mail->isSMTP();
//
/* SMTP server address. */
$mail->Host = "smtp.gmail.com";
//
/* Use SMTP authentication. */
$mail->SMTPAuth = TRUE;
//
/* Set the encryption system. */
$mail->SMTPSecure = 'ssl';
//
//set who is sending mail
$mail->setFrom( '[email protected]', 'My Name' );
//
//set login details for gmail account
$mail->Username = '[email protected]';
$mail->Password = 'loing-password';
//
/* Set the SMTP port. */
$mail->Port = 465;
//      
/* Finally send the mail. */
$mail->send();
} catch (phpmailerException $e) {
} catch ( Exception $e ) {
} catch ( \Exception $e ) {
}
//
if(!$mail->send()) {
$mail_failure = "Something wrong happened. Mail was not sent."; 
$_SESSION["mail-failure"] = $mail_failure;
header("Location: form-errors.php");
} else {
$mail_success = "Mail sent successfully. Thank you.";   
$_SESSION["mail-success"] = $mail_success;
header("Location: form-success.php");
};
exit;

Solution

  • You're sending a message twice, and the second time it's outside the try block, so any errors that happen there will not be caught. You're also catching non-existent exceptions. Do it like this:

       $mail->send();
    } catch ( Exception | \Exception $e ) {
        $_SESSION["mail-failure"] = "Something went wrong. Mail was not sent: " . $e->getMessage();
        header("Location: form-errors.php");
        exit;
    }
    $_SESSION["mail-success"] = "Mail sent successfully. Thank you.";
    header("Location: form-success.php");
    };