我想知道是否存在异常/错误,这会使您的代码跳转到一个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;
是否有一种程序可能会出现错误,忽略此块中的两个语句? 或者我应该这样做:
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;
答案 0 :(得分:7)
你可以抛出任何来自TObject
的东西。为了捕获每个这样的类,您需要在TObject
语句中指定on
。
异常类型的声明与其他类一样。实际上,可以使用任何类的实例作为异常,但建议从SysUtils中定义的SysUtils.Exception类派生异常。
实际上,我知道没有任何代码可以抛出任何不是Exception
的代码,尽管@TLama在评论中指出了旧版已弃用的VCL类中的一个示例。当然StrToInt
只会抛出Exception
后代。
如果您不需要访问异常对象,则可以使用普通except
子句而不使用on
语句。
try
....
except
// deal with all exceptions
end;
或者您可以使用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
这消除了处理任何异常的需要,并使您的代码更具可读性。
我知道StrToInt
只是一个例子,但它很好地证明了试图避免处理异常的好处。