A mysterious exception, which after I scratched my head for quite a while, turned out to be a simple overlook.
In a recent testing of a new internal beta release of some software , we came across a fatal exception thrown from the main program by the end of the simulation run. It happened when the program was trying to export the data to a network SQL server.
What was perplexing is that the exception only happened on testing machines; on the developer’s machine, everything seemed normal.
After pulling some of my hairs, it turned out –
On the development machine, we have the capacity-limited SQL Server Express 2008 R2 installed for debugging and testing purpose. When developing, this server is restricted as a local server and set as the default database connection. The system has a separate ini file that overwrites the default setting and specifies the real database server to connect.
The SQL server connection instance, when created and initialized with its ctor, uses the default connection set up, which will try to create a connection in the first place to the local SQL server on the development machine. Something like this:
lvSQLConn := TMSSQLConnection.Create;
lvSQLConn.ServerAddress := (server address specified from the ini file)
Therefore the default connection happens during the construction. Of course, when running on the development machine, there will be absolutely no problem, because that local SQL server will always be available to access as Named Pipe. However, on the deployment machine, that local SQL server becomes inaccessible, hence an exception (something like “Server doesn’t support requested protocol“) is thrown right in the middle of construction, which as you can see from the code, is not caught by the try-except-finally, but caught by its host, which has no idea about the type of exception.
The fix is very simple and straightforward:
- Move the class construction line into the try-except-finally;
- Turn off the default connection (i.e., set the Active := False for the data access component during design time).
The morale of this story?
- Be wary of (or try not to do) resource allocation during an object construction;
- Be careful with class constructor so exceptions would not be thrown, or if thrown, get properly handled.