Laravel catch Eloquent "Unique" field error

add this code inside class Handler (exception)

if($e instanceof QueryException){
        $errorCode = $e->errorInfo[1];          
        switch ($errorCode) {
            case 1062://code dublicate entry 
                return response([
                    'errors'=>'Duplicate Entry'
                ],Response::HTTP_NOT_FOUND);    
                break;
            case 1364:// you can handel any auther error
                return response([
                    'errors'=>$e->getMessage()
                ],Response::HTTP_NOT_FOUND);                        
                break;      
        }
     }
    ...
    return parent::render($request, $exception);

The long (a little bit weird) way, but works for any Databases

You can use Doctrine's ExceptionConverterInterface You should install package doctrine/dbal

And find the implementation of this interface by calling

app('db.connection')->getDoctrineConnection()->getDriver()->getExceptionConverter()

or

app(\Illuminate\Database\DatabaseManager::class)->connection()->getDoctrineConnection()->getDriver()->getExceptionConverter()

It applies Doctrine\DBAL\Driver\Exception as a first argument

You can get internal Doctrine\DBAL\Driver\PDO\Exception which implements this interface and instantiate it from your PODException

You can get your PDOException from QueryException this way:

$previous = $queryException->getPrevious();

if ($previous && ($previous instance \PDOException)) {
// ...
}

So, the final solution looks like:

$exceptionConverter = app('db.connection')->getDoctrineConnection()->getDriver()->getExceptionConverter()

$previous = $queryException->getPrevious();

if ($previous && ($previous instance \PDOException)) {
    $driverException = $exceptionConverter->convert($previous, null);

    if ($driverException instanceof \Doctrine\DBAL\Exception\UniqueConstraintViolationException) {
        // Our Exception is about non-unique value
    }
}

Please do not use this code in production :)


I'm assuming you use MySQL, it's probably different for other systems

Okay first, the error code for duplicate entry is 1062. And here's how you retrieve the error code from the exception:

catch (Illuminate\Database\QueryException $e){
    $errorCode = $e->errorInfo[1];
    if($errorCode == 1062){
        // houston, we have a duplicate entry problem
    }
}