Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 德尔菲。在整个代码中使用try/except。邪恶?_Delphi_Exception - Fatal编程技术网

Delphi 德尔菲。在整个代码中使用try/except。邪恶?

Delphi 德尔菲。在整个代码中使用try/except。邪恶?,delphi,exception,Delphi,Exception,这是一个相当理论化的问题 我在最近的一个项目中遇到过这种做法——几乎每个过程和函数都包含在try/except子句中,如下所示: function TMyClass.DoFoo(aBar: Integer): Boolean; begin try .. do something .. // Proper checks for common errors inside Result := True; except LogException(ClassName + '

这是一个相当理论化的问题

我在最近的一个项目中遇到过这种做法——几乎每个过程和函数都包含在try/except子句中,如下所示:

function TMyClass.DoFoo(aBar: Integer): Boolean;
begin
  try
    .. do something .. // Proper checks for common errors inside
    Result := True;
  except
    LogException(ClassName + '.DoFoo'); // Write exception to log
    Result := False; // Indicate function did not performed what it was asked for
    // Exit without re-raising exception
  end;
end;

procedure TMyClass.Buzz(Sender: TObject);
begin
  try
    .. do something .. // Proper checks for common errors inside
  except
    LogException(ClassName + '.DoFoo'); // Write exception to log
    // Exit without re-raising exception
  end;
end;
这看起来像是重复了很多次。然而,我可以看到它背后的某种逻辑。如果将每个过程和函数包装到
try..except
中,您将知道异常的大致位置,并让程序继续工作,而不会向用户弹出崩溃消息,但将它们写入日志以供将来分析

然而,这种做法被认为是邪恶的。这到底是为什么

编辑:

  • 这是一个关于我将要参与的项目的问题,它不是我自己发明的
  • 我非常了解madExcept,并且我在其他项目中使用它
  • 该项目中的功能和程序像往常一样布置,没有迹象表明程序被编写为功能,仅用于替换异常流

您的示例创建了更复杂的代码,在任何情况下,您都可以更好地使用广受尊敬的附加工具,例如,它不仅可以捕获任何异常,还可以创建—并记录—一个奇妙的堆栈跟踪,让您能够找到错误发生的点,甚至在客户投诉之后!该工具已经存在多年了,还可以配置为通过电子邮件向您发送异常日志和/或自动重新启动应用程序。我相信开源绝地图书馆中也有一个工具,可以以类似的方式创建堆栈跟踪。

有各种各样的原因说明这是一个非常糟糕的想法

异常处理现在正在驱动所有函数的设计。他们现在都需要返回布尔人。任何实际返回值都必须传递参数。这将破坏代码的可读性和函数的可组合性

现在需要检查每个函数调用的返回值,并向上传播该异常。因此,您放弃了异常处理的所有好处。异常的好处在于,您可以在很大程度上区分正常流和异常流。随着您提议的变化,车头和车头的车流异常流畅

另一个大问题是强制代码尽早处理错误。但是引发异常的代码可能无法处理错误。如果让错误向上浮动,那么代码可以在能够处理错误的地方处理错误


如果您希望程序记录错误的详细信息,而不向用户显示消息,那么通过异常处理很容易实现。您可以使用诸如madExcept、EurekaLog或JclDebug之类的工具来帮助全面地记录日志

我不熟悉Delphi如何处理异常,但在其他语言(如Java)中,使用
try通常在性能方面更昂贵。。。catch
而不是使用
if
-语句。另外,请在
中包装整个函数体,然后重试。。。除此之外
这样做似乎使开发人员没有花任何时间思考可能出现的错误,而是说“让我们抓住每一个错误的情况,并以相同的方式处理它们”。@Michael:这是两点-较慢的代码和防御性的编码。当然,函数内部也有错误处理。不确定我是否会称之为防御性编码(防御性编码通常是一件好事)。我会称之为偏执狂或无知的编码。@Rudy:这并不是那么无知-这些函数/过程中有各种各样的检查。@David:请不要把话塞进我的嘴里,也不要把它当成个人的东西。我没有说“这是一个好主意”,也没有说“删除错误检查是适当的”。我已经说过,这不是我的代码,也不是我决定保持这样的状态。据我所知,在适当的地方有错误检查。只是异常被抑制并记录。我提出这个问题是为了有一个坚实的基础来解释为什么它是邪恶的。然而,从答案来看,似乎并没有什么确凿的事实和偏见。这不是一个建议,我很清楚这一点(将补充到问题中)。问题是“然而这种做法被认为是邪恶的。到底为什么?”“你的建议会产生更复杂的代码”,我认为这是一个重要的事实,不是吗?此外,异常处理通常会影响性能(在创建、跟踪和清理基于帧的异常处理程序时会产生开销-向量化异常处理程序效率更高,但使用较少)。这也给您带来了更大的负担,让您首先知道哪些代码可以也不能引发异常。至少,您应该尽可能消除
try/except
块,并使用
TApplication.OnException
事件来记录未捕获的异常,如果不使用MadExcept或其他类似产品,我只是想帮上忙。如果你知道madExcept,那么你应该在写这篇文章时包括这句话,而不是在我回复后再加上#2:不一定,看起来崩溃的函数只是声明为等同于失败的函数#3:如果内部函数由于任何原因失败,那么父函数无论如何都要处理它#2是的。如果函数失败,并且没有提升,那么无论如何都不能插入#必须有人来处理。但不一定是直接的呼叫者。您的方法会导致每个函数中的错误处理代码。是的,每一个都是。我讨厌同意海夫南先生的观点,但在这种情况下我同意。