Using nested try / finally "try / except" commands
I saw this code posted here on StackOverflow:
with TDownloadURL.Create(nil) do try URL := 'myurltodownload.com'; filename := 'locationtosaveto'; try ExecuteTarget(nil); except result := false; end; if not FileExists(filename) then result := false; finally free; end; Unable to simplify:
Result:= FALSE; <--------- Compiler complains DeleteFile(Dest); dl:= TDownloadURL.Create(NIL); TRY dl.URL:= URL; dl.FileName:= Dest; dl.ExecuteTarget(NIL); Result:= FileExists(Dest); FINALLY dl.Free; END; Final result: = ... will never be executed if something went wrong in "ExecuteTarget", because the program will go directly to "finally". Correctly? Thus, the function will return FALSE. Am I doing something wrong?
PS:
- I intend to use this code in a stream.
- I just put the function in Delphi and the compiler complaint on the first line: "The assigned value has never been used."
The difference is that your second example passes the exceptions back to the caller, and the original traps them and returns false. I would characterize this coding style like this: "I don't care why it failed, I don't care if it succeeded." Which may be reasonable in some cases (for example, when trying to download an update).
Thus, your code is very different from the original in this way - you expect the caller to handle exceptions that are not in the source code.
In addition, the compilerβs complaint is that there is no branch in your code - either if the work and the result are determined by the second assignment, or you have an exception, and the result does not matter.
Result := FALSE; // <--------- Compiler complains DeleteFile(Dest); dl := TDownloadURL.Create(nil); try dl.URL := URL; dl.FileName := Dest; dl.ExecuteTarget(nil); Result := FileExists(Dest); finally dl.Free; end; In the original, if ExecuteTarget throws an exception, it will still test the file name.
In your case, if ExecuteTarget throws an exception, the result will always be false.
In addition, if you did not miss a line in the original, if ExecuteTarget completed successfully, and the file exists, result will never be set.
The first version is just an exception and never rises to the upper subscribers, it considers the exception as a false return. For your simple version, an exception will be thrown.