是否存在一般性E未捕获的异常:异常?

Pie*_*r B 3 delphi exception-handling exception

我想知道是否存在异常/错误,这会使您的代码跳转到一个except块但不会被E:exception处理.

 try
   i := StrToInt(s);
   {...do a lot more...}
 except
   on E : EConvertError do begin
     ShowMessage('You need to input a valid number.');
   end;
   on E : Exception do begin
     ShowMessage('Something went wrong.');
     Raise; 
   end;
 end;
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以让一个程序错误地忽略这个除了块之外的两个语句?或者我应该这样做:

 try
   i := StrToInt(s);
   {...do a lot more...}
 except
   on E : EConvertError do begin
     ShowMessage('You need to input a valid number.');
   end;
   else begin  // swapped on e : Exception with else
     ShowMessage('Something went wrong.');
     Raise; 
   end;
 end;
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 7

你可以抛出任何衍生出来的东西TObject.为了捕获你需要TObject在你的on陈述中指定的每个这样的类.

文档:

异常类型与其他类一样被声明.实际上,可以使用任何类的实例作为异常,但建议从SysUtils中定义的SysUtils.Exception类派生异常.

实际上我知道没有任何代码可以抛出任何不能从中衍生出来的东西Exception,尽管@TLama在评论中指出了旧版已弃用的VCL类中的一个示例.当然StrToInt只会抛弃Exception后代.

如果您不需要访问异常对象,则可以使用except不带on语句的plain 子句.

try
  ....
except 
  // deal with all exceptions
end;
Run Code Online (Sandbox Code Playgroud)

或者您可以使用语句的else子句on作为catch all,再次您将无法立即访问异常对象.

否则,您可以为要捕获的异常指定基类.例如,on E: TObject抓住从中衍生出来的一切TObject.

因此,正如我们所看到的,Exception可能会抛出非衍生的东西.但你必须问自己,你的代码是否曾经这样做过?如果没有那么Exception在你的捕获所有处理程序中测试是最有意义的.这将使您访问成员Exception.当然,人们确实想知道为什么你有一个捕获所有异常处理程序.它们的存在往往表明设计不佳.

继续主题StrToInt,你只需要抓住EConvertError.这就是转换失败时引发的问题.您应该忽略任何其他异常类,因为在您的示例中,代码将不知道如何处理其他任何异常.编写异常处理代码的目标之一是处理您知道如何处理的内容,并忽略其他所有内容.

事实上,TryStrToInt这就是你需要的:

if TryStrToInt(s, i) then
  // do stuff with i
else
  // deal with conversion error
Run Code Online (Sandbox Code Playgroud)

这消除了处理任何异常的需要,并使您的代码更具可读性.

我知道这StrToInt只是一个例子,但它很好地证明了试图避免处理异常的好处.

  • 我不认为我可以根据评论中的描述来调试场景.我刚刚试着回答你提出的问题.请随时详细询问具体方案的新具体问题. (2认同)