Laravel捕获Eloquent“Unique”字段错误

时间:2015-01-10 16:58:09

标签: php laravel laravel-4

我试图识别何时在Laravel中使用eloquent插入记录时因为唯一的字段错误而抛出异常。

我到目前为止的代码是:

try {

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

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

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

谢谢,

加文。

3 个答案:

答案 0 :(得分:42)

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

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

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

答案 1 :(得分:1)

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

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

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

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

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

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

你可以获得内部 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
    }
}

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

答案 2 :(得分:0)

将此代码添加到Handler类中(例外)

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
    android:interpolator="@android:anim/linear_interpolator"
    android:fromXScale="1.0"
    android:toXScale="0.0"
    android:fromYScale="1.0"
    android:toYScale="0.0"
    android:fillAfter="false"
    android:duration="200"
    android:pivotX = "50%"
    android:pivotY = "-90%"
    />
<translate
    android:fromYDelta="0"
    android:toYDelta="50%"
    android:duration="200"
    />
</set>