首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异常--什么是“异常”?

异常--什么是“异常”?
EN

Stack Overflow用户
提问于 2016-11-24 01:01:52
回答 1查看 83关注 0票数 2

我读到异常不应该用于引导应用程序的流程,而应该用于在发生“异常”情况时将应用程序恢复到稳定状态,例如,当您无法连接到数据库时。

一个不应该使用异常的例子是用户提供了一个不正确的登录。这不会是一个例外,因为这是意料之中的事情。

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

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

现在,我使用的是Laravel,所以如果我试图删除一个当前有帖子的类别,我认为它应该抛出一个\Database\Database\QueryException,因为外键约束。因此,我应该依靠这一点并编写如下代码:

代码语言:javascript
复制
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
}

或者,既然我知道我想要我的博客是如何工作的,我应该使用:

代码语言:javascript
复制
if ($category->posts->isEmpty()) {
    $category->delete();
}
else {
    // Tell the user they can't delete...
}

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

EN

回答 1

Stack Overflow用户

发布于 2016-11-24 01:45:51

它是基于观点的,所以我将给你我的观点:异常是强大的,因为你可以用它附加很多信息-你可以把它们“向上调用栈”,而不需要数百个方法检查任何调用的返回值,并将任何东西返回给它们自己的调用者。

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

一个方法应该返回,调用的结果是什么(即使它是void)。如果调用由于任何原因而失败,应该没有返回值。

错误不应该通过返回值来传输,而应该包含异常。

想象一个函数执行db查询:KeyAlreadyExistsExceptionInvalidSyntaxExceptionNullPointerException --很可能你想在代码中完全不同的部分来处理这些“错误”。

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

示例一,简单的“处理”:

代码语言:javascript
复制
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。

代码语言:javascript
复制
 $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.
}

特别是在维护方面,异常有巨大的优势:如果你添加一个新的“异常”--最坏的情况将是一个未处理的异常,但代码执行将中断。

如果你添加了新的“返回错误”,你需要确保每个调用者都知道这些新的错误:

代码语言:javascript
复制
function getUsername($id){
   // -1 = id not found
   $name = doQuery(...);
   if (id not found) return -1;
   else return $name;
}

vs

代码语言:javascript
复制
function getUsername($id){
   $name = doQuery(...);
   if (id not found) throw new IdNotFoundException(...);
   return $name;
}

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

代码语言:javascript
复制
if (getUsername(4)=== -1) { //error } else { //use it }

vs

代码语言:javascript
复制
try{
  $name = getUsername(4);
  //use it
}catch (IdNotFoundException $e){
   //error
}

现在,添加返回代码-2:在实现错误代码之前,第一种方法将假定用户名为-2。第二种方式(另一个异常)将导致执行停止,并在调用堆栈中的某个位置出现未处理的异常。

处理用于错误传输的返回值(任何类型)很容易出错,错误可能会消失在某个地方,变成“错误”的解释结果。

使用异常更安全:您可以使用返回值,也可以使用(已处理或未处理)异常,但没有由于自动转换等原因而导致的“错误值”。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40770303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档