Search code examples
phplaravelemailqueuelaravel-jobs

Email Sent success when i using laravel queue but in cosnole it return fail laravel Queue


I am woring with laravel queue for sending mail to multiple users but when i run command

laravel queue:work

But it getting fail after running but email i recive in mail box so, how can fix this if anyone have any idea then please assist me..
below is the issue i am facing i had changed image into text format now you can see...

> php artisan queue:work 2024-12-18 04:54:20
App\Jobs\AfterAndBeforeBooking0bSendEmailJob 2024-12-18 04:54:24 RUNNING
App\Jobs\AfterAndBeforeBooking0bSendEmailJob 4,768.43ms  FAIL
<?php

namespace App\Jobs;

use Log;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\Mail;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Mail\AfterAndBeforeBookingObSendEmail;

class AfterAndBeforeBookingObSendEmailJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $multi_action_quotes;
    protected $follow_up_quotes;
    protected $future_credit;
    protected $unpaid_quotes;
    protected $partially_quotes;
    protected $update_pax_data;
    protected $mail_from;

    /**
     * Create a new job instance.
     */
    public function __construct($multi_action_quotes, $follow_up_quotes, $future_credit, $unpaid_quotes, $partially_quotes, $update_pax_data, $mail_from)
    {
        $this->multi_action_quotes = $multi_action_quotes;
        $this->follow_up_quotes    = $follow_up_quotes;
        $this->future_credit       = $future_credit;
        $this->unpaid_quotes       = $unpaid_quotes;
        $this->partially_quotes    = $partially_quotes;
        $this->update_pax_data     = $update_pax_data;
        $this->mail_from           = $mail_from;
    }

    /**
     * Execute the job to send email notifications based on the provided data.
     */
    public function handle()
    {
        logger()->info('My Log message before Exception');

        $emails = [];
        $names = [];
        $datasets = [
            $this->multi_action_quotes,
            $this->follow_up_quotes,
            $this->future_credit,
            $this->unpaid_quotes,
            $this->partially_quotes,
            $this->update_pax_data,
        ];

        if ($datasets) {
            // Collect all unique emails from the datasets
            foreach ($datasets as $dataset) {
                if (isset($dataset['data']) && $dataset['data'] !== null) {
                    foreach ($dataset['data'] as $item) {
                        if (!empty($item['created_user_email'])) {
                            $emails[] = $item['created_user_email'];
                        }
                        if (!empty($item['report_to_user_email'])) {
                            $emails[] = $item['report_to_user_email'];
                        }
                    }
                }
            }

            $emails = array_unique($emails);
            $users = User::whereIn('email', $emails)->get(['email', 'name']);

            foreach ($users as $user) {
                $names[$user->email] = $user->name;
            }

            // Send emails to each user with their relevant data
            foreach ($emails as $email) {
                $userName = $names[$email] ?? 'THO User';

                // Filter datasets for the current user
                $filteredData = [
                    'multi_action_quotes' => $this->filterDataByEmail($this->multi_action_quotes, $email),
                    'follow_up_quotes'    => $this->filterDataByEmail($this->follow_up_quotes, $email),
                    'future_credit'       => $this->filterDataByEmail($this->future_credit, $email),
                    'unpaid_quotes'       => $this->filterDataByEmail($this->unpaid_quotes, $email),
                    'partially_quotes'    => $this->filterDataByEmail($this->partially_quotes, $email),
                    'update_pax_data'     => $this->filterDataByEmail($this->update_pax_data, $email),
                ];

                // Skip email if no relevant data for this user
                if (array_filter($filteredData)) {
                    Mail::to($email)->send(new AfterAndBeforeBookingObSendEmail(
                        $filteredData['multi_action_quotes'],
                        $filteredData['follow_up_quotes'],
                        $filteredData['future_credit'],
                        $filteredData['unpaid_quotes'],
                        $filteredData['partially_quotes'],
                        $filteredData['update_pax_data'],
                        $this->mail_from,
                        $userName
                    ));
                }
            }
            throw new \Exception("Message is Logged before the Exception but the job is failed", 1);
        } else {
            Log::error('Error in AfterAndBeforeBookingObSendEmailJob: No datasets provided');
        }
        
    }

    /**
     * Filters a dataset by the given email address.
     *
     * @param array|null $dataset
     * @param string $email
     * @return array|null
     */
    private function filterDataByEmail($dataset, $email)
    {

        if (!isset($dataset['data']) || $dataset['data'] === null) {
            return null;
        }

        // Filter items where the user is either creator or assigned
        $filteredData = array_filter($dataset['data'], function ($item) use ($email) {
            return $item['created_user_email'] === $email || $item['report_to_user_email'] === $email;
        });
        return !empty($filteredData) ? ['data' => array_values($filteredData)] : null;
    }
}

Solution

  • If there is an error in the queue you can check it in failed_jobs table if you migrated that table.

    I think there is an issue with your queue connection. If you are using your database queue connection like below in "queue.php".

    'connections' => [
      'database' => [
        'driver' => 'database',
        'table' => 'jobs',
        'queue' => 'default',
        'retry_after' => 90,
      ]
    ]
    

    Inside the .env, ensure you are using the database queue by setting "QUEUE_CONNECTION=database." You can also add the following line in your job class constructor to tell your class to use the database queue.

    $this->onConnection('database');