'Laravel whole batch is cancelled if one Job fails

I'm working on a Laravel project that uses the Batching feature to batch a bunch of Jobs into a Batch. In my context, I have around 50 jobs in a batch, each job has a max tries of 3, if one job out of the 50 fails due to it exceeding the maximum retries then the entire batch is cancelled, I don't want this as the other 49 jobs may very well succeed, how can I prevent the batch from failing unless all jobs fail in a batch?

My existing functionality takes a CSV, chunks the CSV into smaller ones and then each smaller one is it's own job to process as part of a batch...

/**
* Create chunked CSVs
*/
protected function createChunkedCSVs($schedule)
{
    $this->updateSchedule($schedule->id, 'generating_batches');

    try {
        // get the CSV we stored
        $storagePath = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix();
        $data = file($storagePath . $schedule->csv_path);

        // get file name
        $name = $schedule->csv_name;
        $batchName = $name;

        // chunk the CSV into small jobs of 150 customers per Job
        // so that they can be inserted quicker (originally 1,000)
        $chunks = array_chunk($data, 150);

        // header and batch
        $header = [];
        $batch = Bus::batch([])->name("Customer Import ($batchName)")->dispatch();

        // begin chunking
        foreach ($chunks as $key => $chunk) {
            $data = array_map('str_getcsv', $chunk);

            if ($key === 0) {
                $header = $data[0];
                unset($data[0]);

                // validate headers exist
                $isValid = $this->validateHeadersExist($batch, $header, $schedule);

                if ((isset($isValid) && !empty($isValid)) && $isValid == 'cancel') {
                    return;
                }

            }

            $batch->add(new CustomersCsvProcess($name, $data, $header));
        }

        if (!$batch) {
            $this->updateSchedule($schedule->id, 'error');
        }

        $this->setBatch($schedule->id, $batch->id);
        $this->updateSchedule($schedule->id, 'processing_jobs');
    } catch (\Exception $e) {
        $this->updateSchedule($schedule->id, 'error');
    }

    // clean storage directory
    try {
        Artisan::call('csv:storage:clear --hours=0.25');
    } catch (\Exception $e) { }

    // update schedules
    try {
        Artisan::call('csv:update:finished');
    } catch (\Exception $e) { }
}


Solution 1:[1]

You probably already solve it, but..

You need to add allowFailures() to the batch

$batch = Bus::batch([])->name("Customer Import ($batchName)")->allowFailures()->dispatch();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fabi Curti