Laravel 捕获 Eloquent "Unique" 字段错误

Laravel catch Eloquent "Unique" field error

我正在尝试识别在 Laravel 中使用 eloquent 插入记录时由于唯一字段错误而抛出异常。

我目前的代码是:

try {

    $result = Emailreminder::create(array(
                       'user_id' => Auth::user()->id,
                       'email' => $newEmail,
                       'token' => $token,
              ));

} catch (Illuminate\Database\QueryException $e) {
    return $e;
}

它抛出异常好吧,我只是不知道如何将其识别为列重复错误?

谢谢,

加文

我假设你使用 MySQL,它可能与其他系统不同

好的,首先是 duplicate entry is 1062 的错误代码。以下是从异常中检索错误代码的方法:

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

在 class 处理程序(异常)中添加此代码

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);

(有点奇怪) 方式,但适用于任何数据库

你可以使用 Doctrine 的 ExceptionConverterInterface 你应该安装包 doctrine/dbal

并通过调用找到该接口的实现

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

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

它应用 Doctrine\DBAL\Driver\Exception 作为第一个参数

你可以得到 internal Doctrine\DBAL\Driver\PDO\Exception 它实现了这个接口并从你的 PODException

实例化它

您可以通过以下方式从 QueryException 获取 PDOException:

$previous = $queryException->getPrevious();

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

所以,最终的解决方案如下:

$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
    }
}

请不要在生产中使用此代码:)