创建FileStream时如何处理异常
我有一个这样的函数,我想重构
function Myfunction(sUrl, sFile: String) : Boolean;
var
GetData : TFileStream;
begin
Result := False;
//if the line below fails, I get an unhandled exception
GetData := TFileStream.Create(sFile, fmOpenWrite or fmCreate);
try
try
IdHTTP.Get(sUrl, GetData);
Result := (IdHTTP.ResponseCode = 200);
except
on E: Exception do begin
MessageBox(0, PChar(E.message), 'Niðurhala skrá', MB_ICONERROR or MB_OK);
end;
end;
finally
GetData.Free;
end;
end;
Procedure SomeOtherCode;
Begin
//How can I best defend against the unhandled exception above
//unless the call to the function is packed in a try .. except block
//the code jumps skips the if statement an goes to next
//exception block on the stack
if MyFunction('http://domain.com/file.html', 'c:\folder\file.html') then
ShowMessage('Got the file')
else
ShowMessage('Error !');
End
end;
问题:
请参阅上面过程 SomeOtherCode 中的注释。
此致
I have a function like this, that I would like to refactor
function Myfunction(sUrl, sFile: String) : Boolean;
var
GetData : TFileStream;
begin
Result := False;
//if the line below fails, I get an unhandled exception
GetData := TFileStream.Create(sFile, fmOpenWrite or fmCreate);
try
try
IdHTTP.Get(sUrl, GetData);
Result := (IdHTTP.ResponseCode = 200);
except
on E: Exception do begin
MessageBox(0, PChar(E.message), 'Niðurhala skrá', MB_ICONERROR or MB_OK);
end;
end;
finally
GetData.Free;
end;
end;
Procedure SomeOtherCode;
Begin
//How can I best defend against the unhandled exception above
//unless the call to the function is packed in a try .. except block
//the code jumps skips the if statement an goes to next
//exception block on the stack
if MyFunction('http://domain.com/file.html', 'c:\folder\file.html') then
ShowMessage('Got the file')
else
ShowMessage('Error !');
End
end;
Question:
Please refer to the comment within the procedure SomeOtherCode above.
Best Regards
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
只需将要捕获异常的代码包装在 try..except 块中即可:
Just wrap the code where you want to trap exceptions in a try..except block:
关于异常处理的全部要点有两个:
finally
用于资源清理;您在业务逻辑中经常看到这种情况except 用于对特定异常做出反应(并通过函数结果和中间变量摆脱状态逻辑);您在业务逻辑中几乎看不到它
在您的情况下:
Myfunction
不应返回布尔值,不应包含except
块,也不应执行MessageBox
但只是让异常传播。SomeOtherCode
应包含except
块并告诉用户出了什么问题。示例:
现在代码更加简洁:
except
的地方,无法创建文件
,下载失败
)祝你好运。
——杰罗恩
The whole point about exception handling is two-fold:
finally
is for resource cleanup; you see this often in business logicexcept
is for reacting on specific exception (and getting rid of state logic through function results and intermediate variables); you hardly see it in business logicIn your case:
Myfunction
should not return a Boolean, not contain anexcept
block, and not perform aMessageBox
but just let the exceptions propagate.SomeOtherCode
should contain theexcept
block and tell the user what went wrong.Example:
Now the code is much cleaner:
except
is being handledcannot create file
,download failure
)Good luck with this.
--jeroen
如果您希望函数向用户显示消息并在任何失败时返回 false,请按如下方式编码:
警告
恕我直言,这种设计混合了业务逻辑(例如从互联网获取资源/文件并将其保存到文件中)和用户界面逻辑(例如在出现错误时向用户显示消息)。
一般来说,这是将业务与 UI 逻辑分离的更好方法,因为您的代码是可重用的。
例如,您可能想要重构如下:
明天,如果您正在编写服务或 DataSnap 模块,您可以自由地使用 DownloadToAFile 或者编写一个新的 ServiceDownloadToAFile ,然后将错误写入日志或 Windows 事件,或者发送电子邮件通知 HostAdmin。
If you want your function to show messages to the user and return false on any failure, code it as follows:
Warning
IMHO this design is mixing business logic (such as get a resource/file from the Internet and save it to a file) and user interface logic (such as showing messages to the user in case of errors).
In general, is a better approach to separate business from UI logic, because your code is reusable.
For example you might want to re-factor as this:
Tomorrow, if you're writing a service, or a DataSnap module, you're free to use the DownloadToAFile or maybe to write a new ServiceDownloadToAFile wich in turns writes errors to a log or windows events, or maybe send a email notifying the HostAdmin about it.
一种非常流行的解决方案是完全避免“成功”或“失败”返回值。不使用函数,而使用过程并使用异常处理失败:
然后
这也具有任何人都无法调用该函数并默默地忽略返回值的效果。
One solution which is quite popular is to avoid 'success' or 'failure' return values completely. Instead of a function, use a procedure and handle failures using exceptions instead:
and then
This has also the effect that nobody can invoke the function and silently ignore the return value.
由于某种原因,大多数人滥用 except-finally 组合。正确的顺序是
这可以让您捕获构造函数和析构函数中的异常。
For some reason most people misuse except-finally combination. Correct sequence is
This lets you catch exceptions in constructor and destructor.
您应该只使用一次
try
并获取所有函数代码。You should use only one
try
and get in this your all function code.