如何在Delphi中记录抛出的异常?

5

在我调用函数Foo并想知道这个函数可能会抛出哪些异常时,这种情况经常发生。为了找出答案,我需要查看Foo的实现,但这还不够。Foo可能确实调用一个会引发异常的Bar函数。

有时我甚至会错过Java的检查异常处理机制。

因此,对我来说显然需要记录每个函数可能会抛出的异常:问题是:如何记录?有关于如何记录异常的最佳实践吗?您如何解决这个问题?


6
你为什么想知道哪些异常可能会被抛出?捕获异常的情况非常罕见,因此需要知道特定类型的情况也同样罕见;与此同时,你应该假设异常可能在几乎任何时候被抛出,例如范围检查、浮点数运算、空指针使用时的访问冲突等。 - Barry Kelly
2
@Barry:可能有几个原因。(1)也许我想捕获一个异常并抛出另一个异常(更合适的异常)。 (2)也许我想向用户显示不同的错误对话框(或根据上下文不显示任何错误对话框)。 我所说的并不是像访问违规之类的意外异常。 - jpfollenius
6个回答

4

不是答案,但是因为这些好链接给你点赞。 - Nick Hodges

1

我使用XMLDoc注释。基本上是将一种专用类型的注释添加到接口部分中的代码中,就在属性或方法声明的正上方。这是一个无意义的(当然)例子。如果你在你的代码中添加类似的样式注释,当你在编写代码时调用Code Insight时,它们将像VCL的文档一样弹出。

type
  {$REGION 'TMyClass description'}
  /// <summary>TMyClass is a descendent of TComponent 
  /// which performs some function.</summary>
  {$ENDREGION}
  TMyClass=class(TComponent)
  private
    // your private stuff
    FSomeProp: Boolean;
    procedure SetSomeProp(Value: Boolean);
  protected
    // your protected stuff
  public
    {$REGION 'TMyClass constructor'}
    /// <summary> TMyClass constructor.</summary>
    /// <remarks>Creates an instance of TMyClass.</remarks>
    /// <param>Owner: TObject. The owner of the instance of TMyClass</param>
    /// <exception>Raises EMyObjectFailedAlloc if the constructor dies
    /// </exception>
    {$ENDREGION}
    constructor Create(Owner: TObject); override;
  published
    {$REGION 'TMyClass.Someprop'}
    /// <summary>Someprop property</summary>
    /// <remarks>Someprop is a Boolean property. When True, the
    /// thingamajig automatically frobs the widget. Changing this
    /// property also affects the behavior of SomeOtherProp.</remarks>
    {$ENDREGION}
  property Someprop: Boolean read FSomeProp write SetSomeProp;
  end;

我更喜欢将这些XMLDoc注释包装在区域中,这样除非我想编辑它们,否则它们可以被折叠到一边。我已经这样做了;如果你不喜欢它们,可以删除带有{$REGION}和{$ENDREGION}的行。


只是一个小提示,Documentation Insight 可以自动将文档包含在一个区域中。 - Baoquan Zuo

1

我们使用Javadoc风格的注释来进行文档编写。我们使用一些简单的文本脚本提取信息并生成输出。我们也使用过DelphiCodeToDoc。

在记录异常时,我们强制要求使用@throws标签。


这有什么用呢?由于异常跨越方法边界抛出,你能用得到什么知识呢?我的意思是,如果A调用B,B再调用C等等,A只会抛出异常E,而B会抛出异常F,那么你可以做些什么有用的分析呢? - David Heffernan
@David:你可以将B抛出的异常添加到A的文档中。这样做的区别在于,你只需要在编写A时执行一次,而不是每次使用A时都要执行。不幸的是,这似乎会成为一个维护噩梦——现在更改B的异常处理需要更改所有使用B的函数的文档——非常丑陋。 - jpfollenius
1
@smasher,你需要一个工具来完成这个任务,但我不知道这样的工具怎么可能存在。 - David Heffernan
很高兴看到您正在使用DelphiCodeToDoc :) - TridenT

1

大多数Delphi应用程序都是VCL应用程序。它们不需要一个已检查的异常,因为主消息循环有一个try/except块捕获所有的异常。

虽然如此,记录你的代码可以明确引发哪些异常是一个好的实践。

我会用XMLDoc来做这个(在SO上有各种 问题关于XMLDoc,而且这里有一些Embarcadero的文档)。

注意,底层代码也可以引发异常。根据你对库的影响程度,你可以确定或不能保证这些异常总是相同的。另一件事是操作系统:根据你运行的位置,你可能会得到不同的异常。

--jeroen



1

这对于文档编写看起来很不错 - DevJet.net的文档洞察


1
谢谢。通过其令人印象深刻的所见即所得编辑器,您无需了解任何XML文档语法,可以自然而愉快地编写文档。 - Baoquan Zuo

0

我几乎在所有的 Delphi 项目中使用 PasDoc 进行文档编写。它包括一个“raises”标签,可以实现您所要求的功能。

祝好, - turino


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接