user1506104
user1506104

Reputation: 7076

Laravel 5 SwiftMailer's Send: how to get error code

I am sending email similar to this: Laravel 5: Sending Email. This is how I do it:

$mail_status = Mail::send( 'emails.followup', $data, function( $message ) use ($data) {
             $message->to( $data['email'] )
            ->from( $data['email_from'], $data['email_name'] )
            ->subject( $data['subject'] );
        });

if($mail_status) {
    $ret_status = 'sent';
}
else
    $ret_status = 'sent_failed';

Now, if the $ret_status is 'sent_failed', I want to know what happened. How do I do it? How can I see the message from the mail server?

Here is my .env file:

MAIL_DRIVER=smtp
MAIL_HOST=mail.mydomain.com
MAIL_PORT=465
[email protected]
MAIL_PASSWORD=thepassword
MAIL_ENCRYPTION=ssl

Update

Looks like the approach above is Laravel 4. If you know how to get the error code using Laravel 5+, I can consider it as the correct answer.

Upvotes: 13

Views: 7165

Answers (4)

ChewySalmon
ChewySalmon

Reputation: 614

You want to use a try catch block with a Swift_TransportException exception in your catch and then call getCode() on that exception.

Regardless of your .env settings you can always call getCode() on the exception passed to the catch callback. This returns the code of your exception.

I recommend using \Swift_TransportException inside your catch for the reason that Laravel utilises Symfony's Swift Mailer and these are the type of exceptions it throws; however, it does extend Exception at a deeper level, so you can also use \Exception.

Here's an example:

try {     
    insert mail code here ...           
} 
catch(\Swift_TransportException $e) { // alternatively use \Exception
    // dump error
    dd($e->getCode());
}

The above block will dump the Swift_TransportException code passed to its constructor. If you want the full error message you can also run getMessage().

You can find the complete documentation for the Exception class and subsequent Swift_TransportException here for any other methods you might want to use.


Edit: This is supported in Laravel 4 and above (including 5+ as requested.).

Upvotes: 0

Unamata Sanatarai
Unamata Sanatarai

Reputation: 6637

  1. To get dev version of errors (on screen), set in your .env file APP_DEBUG=true
  2. To get the exact message, do do the try catch, but catch Swift_TransportException https://stackoverflow.com/a/42221501/2119863
  3. You may also, if needed, get the mailer instance via app('mailer') and do some research there.

here is a working example:

try{
    $mail_status = Mail::send( 'emails.followup', $data, function( $message ) use ($data) {
        $message->to( $data['email'] )
        ->from( $data['email_from'], $data['email_name'] )
        ->subject( $data['subject'] );
    });
}catch(\Swift_TransportException $e){
    dd($e, app('mailer'));
}

and the dd() result:

Swift_TransportException {#237 ▼
  #message: """
    Expected response code 250 but got code "530", with message "530 5.7.1 Authentication required\r\n
    "
    """
  #code: 530
  #file: ...

Upvotes: 3

Pubudu Jayawardana
Pubudu Jayawardana

Reputation: 2365

Checking Mail::failures() immediately after Mail::send() will return an array of failed email addresses you tried to send an email to.

However, as far as I know you cannot get the exact error on failure using Mail facade. For that, you need to set the debug true on your .env and check on Laravel log.

Upvotes: 5

AddWeb Solution Pvt Ltd
AddWeb Solution Pvt Ltd

Reputation: 21681

You can use try catch for that, also you mistaken that use $email, $email_from, $email_name, $subject without passing into function scope.

try{
    $mail_status = Mail::send( 'emails.followup', $data, function( $message ) use ($data, $email, $email_from, $email_name, $subject) {
                        $message->to( $email )
                        ->from( $email_from, $email_name )
                        ->subject( $subject );
                    });
    //If error from Mail::send
    if($mail_status->failures() > 0){
        //Fail for which email address...
        foreach(Mail::failures as $address) {
            print $address . ', ';
        }
        exit;
    }  
}
catch(\Exception $e){
    // Get error here
    print $e->getMessage();
    exit;
}

Added failure printing for email address to check email fail for which address.

Upvotes: 5

Related Questions