Wednesday, April 15, 2020

Delphi Tip of the Day - First Chance Exception

I'm in the process of upgrading a very old Delphi program that I wrote with my Turbo Pascal, top-down, structured-programming, mindset. One of the major updates I want is for the data to be in a database. So, I'm cruising right along making very good progress. After two days I finally get the algorithm working. And it's producing good results.

Now it's time to get those results into a database table. No big deal. FDMemtable and LocalSQL will do the trick. I'll just add a DataModule to the project. Drop in the necessary components. Add the fields using the fields editor.

I get everything working in the IDE. I'm good to go. All I need to do now is add the SQL. I code up the insert statements. I'm very excited. I will soon have the data in a database table. I push F9 and... BOOM!

"What the hell is a First chance exception?"




You've got to be kidding. I was so close. I started googling all over the internet trying to figure out what a First chance exception is. I just wanted an answer. After an hour or two I gave up. I was tired. I was frustrated. I'll deal with it in the morning. Off to bed I went.

"It turned out to be a very simple fix!"


The next day with a fresh attitude I returned to my project. It turns out this was a very simple fix. I didn't see or think about this the night before. When I added the DataModule to the project it was added to the bottom of the list.




The OnCreate method of Form1 calls the logic in another unit, which in-turn communicates with DataModule1. Because DataModule1 is created after Form1 gets created it caused an exception. All I had to do was move the DataModule1 before Form1.


I literally had the cart before the horse. I remember getting burned by this in the past but totally forgot about it.

Enjoy!
Semper Fi,
Gunny Mike

Feedback is always appreciated.

4 comments:

  1. When an exception is thrown at runtime, it happens in 2 stages. The exception is first given to an attached debugger, if any, to allow the debugger a "first chance" at processing the exception before your code EVER sees it. Sometimes exceptions can be resolved by the debugger itself. But if a debugger does not discard the exception, only then is it passed back to your code for normal handling (so that a catch() block in your code can, you know, catch the exception).

    ReplyDelete
  2. Never let the IDE auto create anythiong for you except the primary form. Everything else create yourself (and destroy when you no longer need it) and DEFINITELY avoid those global references. While it is handy for novices, it also means they never really understand what is going on and why things late on go so badly when they try more advanced things.

    ReplyDelete
    Replies
    1. So true Xepol! I'm working on a large scale app carefully reducing these auto-created references until I reach just the main form...and there were hundreds when I started. Only 45 to go... First attempts to replace all with singleton functions just to get them under control resulted in AVs everywhere due to the shear amount of interdependencies. One of my first steps in setting up a new Delphi install, disable that auto-create.

      Delete