例外 - 什么是"特殊"?

时间:2016-11-23 17:01:52

标签: php laravel exception

我已经读过,异常不应该被用于指导您的应用程序的流程,但是应该用于将应用程序恢复到稳定的状态,当某些事情发生异常时,#34;异常"例如,当您无法连接到数据库时。

不应使用例外的示例是提供错误登录的用户。它不会是一个例外,因为它预计会发生这种情况。

我不确定以下情况是否例外:

我目前正在设计一个简单的博客。 A"帖子"被分配给一个"类别"。在我的帖子表中,我有一个带有外键约束的category_id字段。

现在,我正在使用Laravel,所以如果我尝试删除当前在其中有帖子的类别,我相信它应该因为外键约束而抛出\ Illuminate \ Database \ QueryException。因此,我应该依赖于此并编写如下代码:

try {
    $category->delete();
}
catch (\Illuminate\Database\QueryException $e) {
    // Tell the user that they can't delete the category because there are posts assigned to it
}

或者因为我知道我希望我的博客如何工作,我应该使用:

if ($category->posts->isEmpty()) {
    $category->delete();
}
else {
    // Tell the user they can't delete...
}

任何建议都将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

这是非常基于意见的,所以我会给你我的意见: 例外是强大的,因为你可以附加大量的信息 - 你可以发送它们"向上调用堆栈"没有方法的hundrets检查任何调用的返回值并返回任何给他们自己的调用者。

这使您可以轻松处理callstack中所需图层的错误。

方法应该返回,调用的结果(即使它是无效的)。如果呼叫因任何原因失败,则应该返回值。

错误不应该通过returnvalues传输,但有例外。

想象一个执行数据库查询的函数:KeyAlreadyExistsExceptionInvalidSyntaxExceptionNullPointerException - 很可能你想要处理这个"错误"在代码中的不同部分。

(一个是代码错误,一个是查询错误,一个是逻辑错误)

示例一,轻松"处理":

try{
  method1(1);
}catch (Exception $e){
  //Handle all but NullpointerExceptions here.
}
---
method1($s){
  try{
    method2($s+2);
  } catch (NullPointerException $e){
    //only deal with NPEs here, others bubble up the call stack.
  }
} 
---
method2($s){
  //Some Exception here.
}

示例二 - 您可以看到所需的"嵌套",此处堆栈深度仅为2。

 $result = method1(1);
 if ($result === 1){
   //all good
 }else{
  //Handle all but NullpointerExceptions here.
 }
 ---
 method1($s){
   $result = method2($s+2);
   if ($result === 1){
     return $result;
   }else{
     if ($result === "NullPointerException"){
       //do something
     }  
 } 

method2($s){
  //Exception here.
}

特别是对于维护,例外具有巨大的优势:如果你添加一个新的"异常" - 最坏的情况将是未处理的异常,但代码执行将中断。

如果您添加新的"返回错误",您需要确保每个来电者都知道这些新错误:

function getUsername($id){
   // -1 = id not found
   $name = doQuery(...);
   if (id not found) return -1;
   else return $name;
}

VS

function getUsername($id){
   $name = doQuery(...);
   if (id not found) throw new IdNotFoundException(...);
   return $name;
}

现在考虑两种情况下的处理:

if (getUsername(4)=== -1) { //error } else { //use it }

VS

try{
  $name = getUsername(4);
  //use it
}catch (IdNotFoundException $e){
   //error
}

现在,您添加返回代码-2:第一种方式将假定用户名为-2,直到实现错误代码。第二种方式(另一种异常)会导致执行在callstack中某处出现未处理的异常。

处理错误传输的返回值(任何类型)都容易出错,错误可能会在某处消失,变成错误的错误"解释结果。

使用异常更安全:您要么使用返回值,要么具有(处理或未处理的)异常,但没有"错误的值"由于autocasts等。