skip to Main Content

I allow users to export a PDF file and save it to their PC and I also allow them to send the PDF through email. Since the PDF can take a while to be generated, if the users decide to send it through email, I created a job that handles the creation of the PDF file & sends by email.

My objective is to prevent the user from having to wait while the file is being generated and while the email is being sent.

Controller

class ReportsController extends Controller
{    
    public function sendByEmail(Request $request)
    {
        $report = (new ReportService)           
            ->setStartAt($request->start_at)
            ->setEndAt($request->end_at)            
            ->setProducts($request->product)
            ->sendByEmail();

        return response()->json([], 200);
    }
}

ReportService

class ReportService
{
    .....
    
    /**
     * Dispatches the job that sends the report by email
     */
    public function sendByEmail(): void 
    {
        dispatch(new AppJobsSendReportByEmail($this));
    }

    /**
     * Downloads / exports the file
     */
    public function download(): string|Exception
    {        
        $url = (new ReportProductService)
            ->setReportService($this)
            ->download();

        return $url;
    }
}

Job SendReportByEmail

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

    /**
     * Create a new job instance.
     */
    public function __construct(public ReportService $reportService) { }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        // Inside the job generates the PDF file
        $url = $this->reportService->download();

        Mail::queue((new AppMailsReport($this->reportService, $url)));
    }
}

On local server everything works great.

On production server I’m getting the error:

SymfonyComponentMimeExceptionInvalidArgumentException: Unable to open path "https://my-website/public/reports/products-report-1693859875.pdf". in /home/my_website/public_html/vendor/symfony/mime/Part/TextPart.php:154

The file actually exists / is generated, which means the mail is sent faster than the file is being generated. How can I prevent this from happening?

I tried Job Batching and create a job also for generating the PDF but got nowhere.

2

Answers


  1. Chosen as BEST ANSWER

    Solved.

    The code is perfectly fine, but for some reason in the production server the absolute url as an attachment it doesn't work properly. It must be a relative path.

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        // HERE: $url must be a relative path (at least in my case...)
        $url = $this->reportService->download();
    
        Mail::queue((new AppMailsReport($this->reportService, $url)));
    }
    

  2. I recently had this error and solved it by creating a function that waits for the file to become available.

        public function sendByEmail(): void 
    {
        $url = $this->download();
        dispatch(new AppJobsSendReportByEmail($this, $url));
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search