After much fussing, I accomplished this by embedding the related model within the Exception that is stored to the database. You could easily do similar but store only the id within the exception and use it to look up the model later. Up to you...
Wherever the exception that fails the job occurs:
try {
doSomethingThatFails();
} catch (\Exception $e) {
throw new MyException(OtherModel::find($id), 'Some string error message.');
}
app/Exceptions/MyException.php:
<?php
namespace App\Exceptions;
use App\Models\OtherModel;
use Exception;
class MyException extends Exception
{
/**
* @var OtherModel
*/
private $otherModel = null;
/**
* Construct
*/
public function __construct(OtherModel $otherModel, string $message)
{
$this->otherModel = $otherModel;
parent::__construct(json_encode((object)[
'message' => $message,
'other_model' => $otherModel,
]));
}
/**
* Get OtherModel
*/
public function getOtherModel(): ?object
{
return $this->otherModel;
}
}
That will store a string containing an object to the exception column on the failed_jobs table. Then you just need to decode that later on...
app/Models/FailedJob (or just app/FailedJob):
/**
* Return the human-readable message
*/
protected function getMessageAttribute(): string
{
if (!$payload = $this->getPayload()) {
return 'Unexpected error.';
}
$data = $this->decodeMyExceptionData();
return $data->message ?? '';
}
/**
* Return the related record
*/
protected function getRelatedRecordAttribute(): ?object
{
if (!$payload = $this->getPayload()) {
return null;
}
$data = $this->decodeMyExceptionData();
return $data->other_model ?? null;
}
/**
* Return the payload
*/
private function getPayload(): ?object
{
$payload = json_decode($this->payload);
return $payload ?? null;
}
/**
* Return the data encoded in a WashClubTransactionProcessingException
*/
private function decodeMyExceptionData(): ?object
{
$data = json_decode(preg_replace('/^App\\\Exceptions\\\WashClubTransactionProcessingException: ([^\n]*) in.*/s', '$1', $this->exception));
return $data ?? null;
}
anywhere:
$failedJob = FailedJob::find(1);
dd([
$failedJob->message,
$failedJob->related_record,
]);