I am implementing an import functionality using Laravel Excel and pushing the process to a queue. I needed to incorporate validation into this import. After discovering that Laravel Excel's built-in validation doesn't work properly with queues, I implemented custom validation. I'm trying to achieve this using the Validator Facade and ValidationException.
However, after testing, I realized that the catch I added using ValidationException is not working; instead, the catch for Exception is handling the error. I looked into this issue in Laravel documentation and forums but didn't find any solution. Hence, I am seeking an answer here.
Here is the sample code I have implemented:
<?php
namespace App\Imports;
use App\Models\User;
use Exception;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\OnEachRow;
use Maatwebsite\Excel\Concerns\SkipsFailures;
use Maatwebsite\Excel\Concerns\SkipsOnFailure;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Row;
use Maatwebsite\Excel\Validators\ValidationException;
class EngagementImport implements OnEachRow, SkipsOnFailure, WithHeadingRow, WithChunkReading, ShouldQueue
{
use Importable, SkipsFailures;
/**
* @param int business_id
* @return
*/
public function __construct($business_id)
{
$this->business_id = $business_id;
}
/**
* Tweak the data slightly before sending it to the validator
* @param $data
* @param $index
* @return mixed
*/
public function prepareForValidation($data) {
// Modify data if need before validation
}
/**
* List the validation rules
* @return array
*/
public function rules(): array {
return [
'first_name' => 'required',
'last_name' => 'nullable',
'email' => 'required',
];
}
/**
* @param Row $row
* @return \Illuminate\Database\Eloquent\Model|null
*/
public function onRow(Row $row) {
$row = $row->toArray();
try {
$row = $this->prepareForValidation($row);
$validator = Validator::make($row, $this->rules());
$data = $validator->validate();
$user = User::create([
'first_name' => $row['first_name'],
'last_name' => $row['last_name'],
'email' => $row['email']
]);
} catch (ValidationException $e) {
info("---- Validation Error for Import User {$row['first_name']} ----");
info($e->errors());
info("--------------------------------------------------------------");
} catch (Exception $e) {
info('Exception: ' . $e->getMessage() . ' on ' . $e->getLine() . ' line.');
info('----------------- Error row -----------------');
info($row);
info('---------------------------------------------');
}
}
public function chunkSize(): int {
return 1000;
}
}