Laravel 13.36 New Published on

Don't send the email of a cancelled order

A queued mailable now honours #[DeleteWhenMissingModels]: if its order has disappeared in the meantime, the job is removed instead of failing.

Topics covered: MailQueues

New in Laravel 13.36. A mailable queued with SerializesModels only keeps the identifier of its models; the worker reads them again before sending. If a model was deleted in the meantime, it throws a ModelNotFoundException, and the job fails.

For a job (ShouldQueue), the #[DeleteWhenMissingModels] attribute has handled this case for a long time: the job is removed from the queue, without failing. Queued mailables ignored it.

Since Laravel 13.36

Queued mailables read #[DeleteWhenMissingModels], and also #[FailOnTimeout] (an email that runs past its timeout is marked as failed instead of being retried, which could send it twice):

use Illuminate\Queue\Attributes\DeleteWhenMissingModels;

#[DeleteWhenMissingModels]
class OrderShipped extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    public function __construct(public Order $order) {}
}

Your task

When the warehouse ships an order, the "Your order is on its way" email is queued. But a customer sometimes cancels just before the worker gets to it: the order is deleted, and each time a job is added to failed_jobs, where the team finds it the next day.

Make the email of an order that has disappeared simply be dropped.

Where the feature comes from: the original pull request.