Checking passed object existence in Laravel delayed queue job

- 1 answer

Ad

I believe if I pass an Eloquent object to a delayed Laravel job a "findOrFail" method is called to "restore" the object and pass it to the controller of my Job class.

The problem is that the DB record representing the object might be gone by the time the job is actually processed.

So "findOrFail" aborts before even calling the "handle" methods.

Everything seems fine. The problem is that the job now "gets transferred" to the failed jobs list. I know I can remove it from there manually, but that doesn't sound right.

Is there a way to "know" in my job class directly that the passed object "failed to load" or "does not exist" or anything similar?

Basically I would like to be able to do something if "ModelNotFoundException" is thrown while "rebuilding" my passed objects.

Thank you

SOLUTION:

Based on Yauheni Prakopchyk's answer I wrote my own trait and used it instead of SerializesModels where I need my altered behaviour.

Here's my new trait:

<?php

namespace App\Jobs;

use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Database\ModelIdentifier;
use Illuminate\Database\Eloquent\ModelNotFoundException;

trait SerializesNullableModels
{
    use SerializesModels {
        SerializesModels::getRestoredPropertyValue as parentGetRestoredPropertyValue;
    }

    protected function getRestoredPropertyValue($value)
    {
        try
        {
            return $this->parentGetRestoredPropertyValue($value);
        }
        catch (ModelNotFoundException $e)
        {
            return null;
        }
    }
}

And that's it - now if the model loading fails I still get a null and can decide what to do with it in my handle method. And if this is only needed in a job class or two I can keep using original trait everywhere else.

Ad

Answer

Ad

If i'm not mistaken, you have to override getRestoredPropertyValue in your job class.

protected function getRestoredPropertyValue($value)
{
    try{
        return $value instanceof ModelIdentifier
            ? (new $value->class)->findOrFail($value->id) : $value;
    }catch(ModelNotFoundException $e) {
        // Your handling code;
    }
    exit;
}
Ad
source: stackoverflow.com
Ad