Rajan Rawal
Rajan Rawal

Reputation: 6317

How the laravel Mail::failures() function works?

I've been trying to get the list of recipients who did not get email using laravel Mail::send() function. I am trying following code. for loop is used as because each user to be received customized message.

// First recipient is actual, the second is dummy.
$mail_to_users = ["[email protected]","[email protected]"];
$failures = [];

foreach($mail_to_users as $mail_to_user) {
   Mail::send('email', [], function($msg) use ($mail_to_user){
     $msg->to($mail_to_user);
     $msg->subject("Document Shared");
   });

   if( count( Mail::failures() ) > 0 ) {
      $failures[] = Mail::failures()[0];
   }
}

print_r($failures);

I've been trying all the possible option. I changed the correct mail config in config/mail.php to the wrong one. But if I do this then laravel shows error page, but $failure variable always return empty.

Upvotes: 16

Views: 28576

Answers (3)

Yasin Patel
Yasin Patel

Reputation: 5731

I had the same issue. You can use try..catch statement with multiple catch().So for any type of failure, you will get an email Id in the failure list. I also put a log to get an error message.

Try the below code.

$failures = [];

foreach ($mail_to_users as $mail_to_user) {

    try {
        Mail::send('email', [], function($msg) use ($mail_to_user) {
            $msg->to($mail_to_user);
            $msg->subject("Document Shared");
        });
    }
    catch(\Swift_TransportException $e){

      Log::info('------> err swift:--  '.$e->getMessage()); // for log, remove if you not want it
      Log::info(''. PHP_EOL .'');

      $failures[] = $mail_to_user;
    }
    catch(\Swift_RfcComplianceException $e){
      Log::info('------> err Swift_Rfc:'.$e->getMessage());
      Log::info(''. PHP_EOL .'');

      $failures[] = $mail_to_user;
    }
    catch (Exception $e) {
      Log::info('------> err'.$e->getMessage());
      Log::info(''. PHP_EOL .'');

      $failures[] = $mail_to_user;
    }
}
print_r($failures);

Upvotes: 0

Kevin Bui
Kevin Bui

Reputation: 3035

I am working with a similar issue. When an email fails to be sent, I want to do a few things with it. I read the source code and the Illuminate\Mail\SendQueuedMailable::failed() method indicates that we can add a failed method to the Mailable object to handle the $exception when the email fails.

So we can do this:

class SampleMail extends Mailable
{
    public function failed($e)
    {
        // Do something with the exception when the email fails.
    }
}

As I understand, this only works with queued mailables.

Upvotes: 2

Hasan Tareque
Hasan Tareque

Reputation: 1741

I think there is no way to check email is actually gone to the receipient or not. As long as the email is valid (even though dummy) it will return true. However, Instead of Mail::failures() you can use try catch block as follows:

foreach ($mail_to_users as $mail_to_user) {
            try {
                Mail::send('email', [], function($msg) use ($mail_to_user) {
                    $msg->to($mail_to_user);
                    $msg->subject("Document Shared");
                });
            } catch (Exception $e) {

                if (count(Mail::failures()) > 0) {
                    $failures[] = $mail_to_user;
                }
            }
        }

Upvotes: 5

Related Questions