Databases - Delphi/WebServer Debug Techniques

Delphi has one of the best interactive debuggers available ... but you can't use it with web servers.

There are many types of web servers and Delphi allows you to develop those which can be directly accessed via their own ports. This page applies to both CGI and ISAPI html producers - web servers that are run by other web servers (such as IIS or Apache) and generate html that is normally displayed in a browser.

Running the code | Debug Page | Conditional Debug Trace | Program Trace
Internal Server Error 500 - Undefined Object | Database Connection Error | File not found


Running the code

When developing code, you need to compile and execute the program. Web servers have special problems. Set to a directory available to IIS (or the server of your choice).


Debug Page

I find it useful to define a Debug action to display various configuration parameters (such as database connection info).

By actually coding a separate Debug subroutine makes it easier to call it (fewer parameters).


Conditional Debug Trace

I want a way to turn the debug trace on and off without recompiling the program. One way to accomplish this is to pass a query parameter with the url (query parameters start with a question mark) In the following code, the ?debug=p causes the server to display the trace and other debug data. One issue is that, when the server is run as an ISAPI dll (ie, it stays in memory for days at a time), the trace could get very long because the Trace_Str global parameter is common to all page requests. The example code sets (and clears) a flag based on the value of the debug parameter. This way, the trace string is automatically cleared after each page is generated unless instructed not to. If the trace string was never cleared, it would eventually get large enough to crash the server.


Forms

When using web forms, I sometimes use a checkbox to control displaying the debug information. This code will return a value ONLY IF the box is checked. This code will be hidden ... but still show the debug information.


Program Trace

When rendering a web page, many subroutines are called. This is one method to generate and display a trace.

At the beginning of the application, define Trace_Str as a global variable

In each subroutine, add This will display the trace I use code similar to this to display various variables. Because this technique uses a global variable, the results may be incorrect in a true multiuser system.

CRLF_mc is a global variable I use to add a CR/LF pair to strings, in this case to make the html more readable.


Internal Server Error 500

If you try to access an unallocated object or connect to a database without the right permissions, the browser will display an error - either "page not found" or "Internal Server Error 500". If you are very lucky, there may be more specific information.

Errors in TWebModule_xyz.WebModuleCreate do not produce any 500 errors. To detect/report these problems, set Trace_Str in a try..except block.

These are a couple of common errors. (Common, but hard to trouble shoot.)


Undefined Object

Internal Server Error 500
Exception: EAccessViolation
Message: Access violation at address 00489C37 in module 'Experiments.exe'. Read of address 00000050
Generic error
The page cannot be displayed
HTTP 500 - Internal server error
I don't understand why there are 2 different errors, but both of these errors were caused by exactly the same *.exe file - it tried to access an undefined object. Fixed by adding (caused by removing)


Database Connection Error

When moving a working Delphi application over to web server (by reusing the DataModule), generated the following error
Internal Server Error 500
Exception: EReadError
Message: Error reading KADaoDatabase1.Connected: The Microsoft Jet database engine cannot open the file 'c:\inetpub\wwwroot\rlc\SLP_DB\SamplePrep\Samples.mdb'. It is already opened exclusively by another user, or you need permission to view its data
The solution is in the security settings I can't figure out why some directories inherit security settings from their parent directories (the check box is grayed out) and others don't. It took a couple of days to find this because there were 2 directories under a parent. The parent directory had the "correct" settings and a CGI file in one directory had no problems (the settings were inherited). However, the other directory had inheritance disabled (I don't even know how to do that) and produced this error.

I also don't know why Windows 2000 and Windows XP require different settings - Network vs Everyone

Notice that IIS does not need to be configued (via the control panel) to allow user write premission. The write premission must be set via Windows Explorer.

For more information, see Microsoft KB article 306269 about problems using ASP to access MS Access. (Different language, same problems because both use IIS.) It even suggest using Sysinternals File Monitor (free) to track down the problem.


File not found

This exception was generated trying to open a file that was not there.
Internal Server Error 500
Exception: EReadError
Message: Error reading KADaoDatabase1.Connected: Cannot find Database: c:\inetpub\wwwroot\rlc\SLP_DB\SamplePrep\Samples.mdb


Author: Robert Clemenzi - clemenzi@cpcug.org
URL: http:// cpcug.org / user / clemenzi / technical / Databases / Delphi / WebServers / Debug_Techniques.html