-1

I am using D5 and Synaps with OpenSSL and it is working great. I am trying to handle crashes so have deliberately entered bad data, one try at a time. So far I have handled the induced crashes OK, but I just changed the login Password and tried to login.

gMajorFail:=False;
if not pop3.Login() then
begin
  gMajorFail:=True;
  raise EPOP3.Create('POP3 ERROR: '+IntToStr(pop3.Sock.LastError)+
                     ' When trying to Login to Account');
end;
if gMajorFail then GoTo HadFailure;

Instead of jumping to the HadFailure-Label, it jumps to the last line of code in the procedure.

I have tried using Try/Finally (that's why I am using the Label to GoTo) but it still skips right to the last line of code.

Where am I going wrong and how can I fix it?

Thanks

J...
  • 30,968
  • 6
  • 66
  • 143
  • 2
    Why did you raise an exception at all? – David Heffernan Jul 30 '13 at 06:57
  • After jumping to the last line...will it jump back to where it should be? I had this behavior while debugging an ocx in D2007. It seems to be "normal". – Sherlock70 Jul 30 '13 at 07:52
  • @DavidHeffernan I was wondering that as well but was afraid to ask. – J... Jul 30 '13 at 10:00
  • @DavidHeffernan That code was taken directly from the Samples for Synapse. I assumed from that it would all work as intended. It does, but apparently not when an exception is encountered. –  Jul 30 '13 at 15:30
  • @Sherlock70 Nope, the calling procedure also jumps to the last line in that procedure too. It is the client's D5 I am stuck with using so D2007 behavior? –  Jul 30 '13 at 15:38
  • 1
    @user2175495 I don't think you understand how exceptions change program control flow. – David Heffernan Jul 30 '13 at 15:45
  • @DavidHeffernan I freely admit that and that's why I am asking for help to fix it. I changed the "raise' (as you implied) to "ShowMessage" and it did go to the next line and started to look good. But when it came to closing the Synapse POP system it hung forever. The "Raise" is obviously clearing something within Synapse, and it seems to be in the OpenSSL.DLL which I can't step into. –  Jul 30 '13 at 15:49
  • Start with the documentation: http://docwiki.embarcadero.com/RADStudio/en/Exceptions – David Heffernan Jul 30 '13 at 15:53
  • @user2175495 - you say the calling procedure jumps to the last line also; could you show the calling procedure? I'm guessing that you did not call this method in a `try/except` block. If you haven't written any exception handling then your raised exception will not be handled. – J... Jul 30 '13 at 16:03
  • @DavidHeffernan, that pretty much mimics the Help system for D5 and I mentioned I had read that. The advice there is too general and I was hoping for a quick-fix here. Seems I spent more time here fielding wasted "help" that it took to fix it myself. –  Jul 30 '13 at 17:00
  • @J... Thanks J, but I have solved the problem and now it flows cleanly to the next account if there is one. –  Jul 30 '13 at 17:03
  • @user2175495 another perspective on your "wasted" time here might be that of a squandered opportunity to extend your knowledge and become a better programmer. – J... Jul 30 '13 at 17:07
  • @user OK. Sounds like you don't need any help from us. – David Heffernan Jul 30 '13 at 18:27

1 Answers1

14

oh boy... kill that GoTo with fire.

That said, when you raise an exception that's the end of the line, it does not return control to the remainder of your method - execution is immediately passed to the exception handler (ie: the nearest parent except/finally block is triggered or, if none exists, you get the "unhandled exception" dialog). When you're raising an exception you are essentially throwing up your arms and intend it to mean that your own code has no further error handling that can correct the issue and that there is nothing more your code needs to do. If you need to clean up or otherwise set some remaining things in order, do all of that first and then raise the exception as the last thing you do.

From the documentation :

When an exception is raised - that is, referenced in a raise statement - it is governed by special exception-handling logic. A raise statement never returns control in the normal way. Instead, it transfers control to the innermost exception handler that can handle exceptions of the given class. (The innermost handler is the one whose try...except block was most recently entered but has not yet exited.)

J...
  • 30,968
  • 6
  • 66
  • 143
  • @J... Get back on the Ark and take whosr... with you. :) If it is a valid part of the language then there is no reason not to use it. Besides, the GoTo was added to assist with the handling of the exception. I figure when testing FOR failure, and I assume you test for it as well as success, it is fair game to use whatever it takes. So, no helpful answers eh? I did click the Help and read it, but it never offered a suggestion on how to "handle the exception," which is what I am asking for. David comes the closest with "why raise?" and I will try removing that and go from there. –  Jul 30 '13 at 15:36
  • 1
    Actually, it's the `goto` that I would remove. I asked "why raise?" since it makes no sense to mix two error handling models. In fact `goto` can be useful in languages without exceptions for error handling. You'll find it all through the source code for all modern operating systems, for example. – David Heffernan Jul 30 '13 at 15:46
  • @DavidHeffernan Ther is a lot of stuff following that section that will also throw exceptions and it gave five more exceptions if I didn't try to jump over them. I am trying to "fix" (for free) some old code written by someone else and wanted to get past this as fast as possible. As you can see in the comment above, it is fixed, but hardly in a timely fashion. :) I don't know why most people here seem to think that a discussion on coding practice is helpful when all I wanted was a "do this... and then this..." –  Jul 30 '13 at 17:09