2017-08-10 55 views
0

我有以下代码:Yii2:自定义错误消息时完整性约束违规

try { 
    if ($model->save()) { 
     return $this->redirect(['view', 'id' => $model->id]); 
    } 
} catch (\Exception $e) { 
    $model->addError(null, $e->getMessage()); 
    return $this->render('create', [ 
     'model' => $model, 
    ]); 
} 

但是当我做一个插入与重复键的数据库,显示的错误是不是很友好。

SQLSTATE [23000]:完整性约束违规:1062重复条目 '1-17' 的执行关键 '主要' 的SQL是:INSERT_QUERY

如何自定义的消息时,错误是由于重复键?

回答

1

在尝试运行插入语句之前,您会理想地验证模型
看看unique validator

这样一个规则添加到模型

// a1 and a2 need to be unique together, and they both will receive error message 
[['a1', 'a2'], 'unique', 'targetAttribute' => ['a1', 'a2'], 'message' => 'custom message'], 

调用model->save()应该只是返回false,加入适当的错误消息,并且不会引发任何异常


编辑:
什么我试图在评论中说,做这样的事情一般不是一个好主意:

try { 
    if ($model->save()) { 
     return $this->redirect(['view', 'id' => $model->id]); 
    } 
} catch (\Exception $e) { 
    $model->addError(null, $e->getMessage()); 
    return $this->render('create', ['model' => $model]); 
} 

这应该只是成为

if ($model->save()) { 
    return $this->redirect(['view', 'id' => $model->id]); 
} 
return $this->render('create', ['model' => $model]); 

如果发生任何异常,prod环境下真实的用户只会看到一个通用的状态500消息。这就是为什么我们事先进行验证,以防止例外情况不会在地毯下清扫它们。

这样$model->addError(null, $e->getMessage());是你的风险敏感数据暴露在真实世界中的用户这是一个很大的安全隐患问题尤其严重。

+0

我想补充一点'完整性约束violation's可以在其他情况下发生的,以及(大部分是无效的插入/更新/删除外键字段)。这个例子只是防止一个场景(重复PK)。正确的方法是确定这些发生的位置,并防止应用程序试图通过对用户有意义的验证规则和错误消息来运行它们,而不是定制异常消息 – csminb

+0

您能否解释您的评论?你可以编辑你的答案:)谢谢! – Giest

+2

@Giest我想说你的重点应该是防止[违反约束](https://dev.mysql.com/doc/ndbapi/en/ndb-error-codes-constraint-violation.html)使用更严格的验证规则。我希望编辑的答案可以帮助你。欢呼 – csminb

1

这种方法并没有为我工作:

[['a1', 'a2'], 'unique', 'targetAttribute' => ['a1', 'a2'], 'message' => 'custom message'], 

我想这个基础上,this answer和它的工作:

['a1', 'compare', 'compareAttribute' => 'a2', 'operator' => '!=', 'message' => 'your error message...'], 

编辑:

但是,如果我理解你的问题正确地说,这不是你想要的。你想捕获由于在同一个表中插入两个相等的主键而导致的错误?为什么不使用自动增量主键?

反正你可以使用这样的事情:

[['id'], 'exist', 'skipOnError' => true, 'targetClass' => YourModel::className(), 'targetAttribute' => ['id' => 'YourModelId']], 
+0

引用来自你所链接的答案:'因为唯一的验证器验证属性值在表中是唯一的“,所链接的问题和OP的问题完全不同 – csminb

+0

是的,我不确定我是否正确理解他的问题,这就是为什么我编辑了我的答案,但我还不确定。我希望我不会混淆比我更帮忙.. – ManuelCash

+1

是的,我的桌子有两个主键。我不想使用自动增量,因为我不想要多于一组键。我只想要一条消息来替换错误“SQLSTATE [23000]:完整性约束违规:1062重复...” – Giest

相关问题